【问题标题】:How to compare instances subclasses of @dataclass with same inheritance如何比较具有相同继承的@dataclass的实例子类
【发布时间】:2020-10-22 13:08:54
【问题描述】:

我正在尝试比较从公共基类(也是@dataclass)继承的两个数据类。

继承类的字段是特定于它们的,在比较中不考虑;我只想比较基类属性。

这是我的尝试:

from dataclasses import dataclass, field

@dataclass(order=True)
class Base:
    a: float

@dataclass(order=True)
class ChildA(Base):
    attribute_a: str = field(compare=False)

@dataclass(order=True)
class ChildB(Base):
    attribute_b: str = field(compare=False)


ca = ChildA(1, 'a')
cb = ChildB(2, 'b')
ca < cb

但是,我得到:

TypeError: '<' not supported between instances of 'ChildA' and 'ChildB'

我该如何解决这个问题?

【问题讨论】:

  • 生成的比较方法总是要求参数具有完全相同的类型;无法比较共同祖先的不同子类。见github.com/python/cpython/blob/3.9/Lib/dataclasses.py#L575。您必须自己定义Base.__lt__ 等(尽管请参阅functools.total_ordering 以使这更容易,只需要__eq__ 和另一种方法来生成其余部分)。
  • > "生成的比较方法总是要求参数具有完全相同的类型" 即使我设置了 field(compare=False) 也是如此吗?在比较方法中这些字段不应该被丢弃吗?

标签: python python-3.x python-dataclasses


【解决方案1】:

你应该自己定义Base的比较方法; dataclass 创建的方法要求参数具有精确相同的类型。

from functools import total_ordering

@total_ordering
@dataclass(eq=False)
class Base:
    a: float


    # Both of these are oversimplified. At the very
    # least, handle the error resulting from `other`
    # not having an `a` attribute.

    def __eq__(self, other):
        return self.a == other.a

    def __lt__(self, other):
        return self.a < other.a

【讨论】:

  • 谢谢。但是,由于我将子类中的字段设置为field(compare=False),所以在比较过程中不应该丢弃这些不同的类型吗?根据github.com/python/cpython/blob/3.9/Lib/dataclasses.py#L959,在调用_cmp_fn之前不应该过滤掉这些属性吗?
  • 没有。在查看字段之前,comparison function 会比较每个参数的 __class__ 属性的值,以了解 object identity。只有在确认两者都是 ChildA 实例之后,它才会比较选定的属性值。
  • 我明白了。感谢那。这超出了这个问题,但是您认为值得打开一个功能请求/错误,以便在对象身份检查中支持子类吗?
【解决方案2】:
ca.a < cb.a

两者都有父类的属性'a',使用'.a'访问属性

【讨论】:

  • 这是一个简化的示例,只有一个可比较的属性。如果我有更复杂的数据类和更多属性怎么办?当然我仍然可以将它们分组到一个元组中(例如(ca.a, ca.b, ca.c) &lt; (cb.a, ca.b, ca.c)),但我想知道是否有更直接的方法?
  • 哦,我明白了,我会将问题添加为书签,稍后再返回
猜你喜欢
  • 2021-12-13
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
相关资源
最近更新 更多