出于好奇:为什么python3不将__dict__比较作为默认相等实现?

4 投票
1 回答
1209 浏览
提问于 2025-04-30 11:49

在Python中(我用的是3.4版本),你可以用 this == that 来比较两个对象是否相等,这跟大多数其他编程语言是一样的。

当你比较基于类的对象时,Python会调用这个类的 __eq__ 方法来进行比较。

不过,如果你像下面这样做:

class Foo:
    def __init__(self, bar):
        self.bar = bar

one = Foo('text')
two = Foo('text')

调用 one == two 会返回 False,因为Python只检查对象的身份,而不是它们的数据是否相等。

这就导致你需要实现很多 __eq____ne__(不等于)方法,完全是这样:

def __eq__(self, other):
    return (isinstance(other, self.__class__)
        and self.__dict__ == other.__dict__)

def __ne__(self, other):
    return not self.__eq__(other)

那为什么我们必须这样做呢?

有没有人知道,为什么他们决定不把字典比较方法作为类对象的默认实现呢?

这样做可能会有什么不好的地方呢?

暂无标签

1 个回答

5

为什么我们必须这样做?

因为明确的比隐含的要好。

你假设两个实例是相等的,仅仅是因为它们的属性相同;但这并不一定是对的。比如,有些类使用私有属性来跟踪缓存的数据。那么,有些类有很多属性,但并不需要支持相等性,这样的话,它们为什么要承担额外的性能损失呢?

与其做这样的假设,Python要求你明确地定义相等性。这还有一个好处,就是如果你不想支持实例之间的相等性,你就不需要再去禁用这样的相等性测试。

对于简单的情况,使用 vars(self)self.__dict__ 是可以的,没问题:

def __eq__(self, other):
    if not isinstance(other, __class__):
        return NotImplemented
    return vars(self) == vars(other)

def __ne__(self, other):
    if not isinstance(other, __class__):
        return NotImplemented
    return not self.__eq__(other)

返回 NotImplemented 可以确保另一个对象也有机会实现相等性测试。

撰写回答