出于好奇:为什么python3不将__dict__比较作为默认相等实现?
在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
可以确保另一个对象也有机会实现相等性测试。