我有几个数据类,我想修改比较方法。我实现了这个类:
@dataclass
class ComparisonMixin:
def __eq__(self, __o: object) -> bool:
result = True
for s, o in zip(self, __o):
if isinstance(s, datetime.datetime) and isinstance(o, datetime.datetime):
margin = datetime.timedelta(days=3)
result = result and s - margin <= o <= s + margin
elif o:
result = result and s == o
return result
def __iter__(self) -> Iterator[datetime.datetime | float | str]:
return iter(astuple(self))
但是从此类继承时,比较并不符合预期。
在示例中,此类不会根据 ComparisonMixin 中的 eq 方法进行比较:
@dataclass
class Bloodsample(ComparisonMixin):
datetime: datetime
substance: str
value: float
category: Optional[str] = None
这应该评估为 true,但它评估为 false:
sample = Bloodsample(datetime(2024, 1, 9), "hemoglobin", 9.5, "hematology")
sample_with_none_value = Bloodsample(datetime(2024, 1, 9), "hemoglobin", 9.5, None)
assert sample == sample_with_none_value
# Raises AssertionError
我怀疑MRO是错误的,但是数据类中没有
__mro__
属性。如果直接在子类中实现,则比较将按预期进行。
使用数据类实现此目的的最佳方法是什么?
我尝试通过在子类的数据类装饰器中设置
eq=False
来手动忽略比较方法。这可行,但感觉不对,所以我想听听是否有更好的解决方案。
因为
datclasses.dataclass
代码生成器 将创建一个 __eq__
来覆盖您的 mixin。因此,如果您想防止这种情况,请对装饰器使用适当的参数:
@dataclass(eq=False)
class Bloodsample(ComparisonMixin):
datetime: datetime
substance: str
value: float
category: Optional[str] = None