解决办法是你自己
__eq__
方法和集合
eq=False
所以数据类不会生成自己的(尽管检查
docs
最后一步是不必要的,但我认为还是要明确一点。
import numpy as np
def array_eq(arr1, arr2):
return (isinstance(arr1, np.ndarray) and
isinstance(arr2, np.ndarray) and
arr1.shape == arr2.shape and
(arr1 == arr2).all())
@dataclass(eq=False)
class Instr:
foo: np.ndarray
bar: np.ndarray
def __eq__(self, other):
if not isinstance(other, Instr):
return NotImplemented
return array_eq(self.foo, other.foo) and array_eq(self.bar, other.bar)
编辑
通用数据类的通用快速解决方案,其中一些值是numpy数组,而另一些不是
import numpy as np
from dataclasses import dataclass, astuple
def array_safe_eq(a, b) -> bool:
"""Check if a and b are equal, even if they are numpy arrays"""
if a is b:
return True
if isinstance(a, np.ndarray) and isinstance(b, np.ndarray):
return a.shape == b.shape and (a == b).all()
try:
return a == b
except TypeError:
return NotImplemented
def dc_eq(dc1, dc2) -> bool:
"""checks if two dataclasses which hold numpy arrays are equal"""
if dc1 is dc2:
return True
if dc1.__class__ is not dc2.__class__:
return NotImplmeneted # better than False
t1 = astuple(dc1)
t2 = astuple(dc2)
return all(array_safe_eq(a1, a2) for a1, a2 in zip(t1, t2))
# usage
@dataclass(eq=False)
class T:
a: int
b: np.ndarray
c: np.ndarray
def __eq__(self, other):
return dc_eq(self, other)