倒行逆施:
“西狂” 杨过所创 黯然销魂掌 第十七式
掌法逆中有正,正反相冲,自相矛盾,不能自圆其说
出掌时需要 头下脚上,倒过身子,源自 “西毒” 欧阳锋
在我们定义一个类的时候,常常想要将这个类实例化的多个对象之间进行比较,一般情况下,当两个对象中的属性一致的时候,我们会认为这两个对象是相等。
class Person:
def __init__(self, name, gender):
self.name = name
self.gender = gender
a = Person('小红', '女')
b = Person('小红', '女')
print(a == b) # False
print(id(a), id(b)) # 84716680 84716872
在上边这段代码中,我们使用同一个类实例化了两个对象,这两个对象的属性完全一致,当我们使用 == 进行判断时,却得到了 False
,这是因为 == 默认会使用 内存地址 进行比较,那么我们能否重新实现这部分判断的逻辑呢?
__eq__ 方法
这时候我们就需要用到 __eq__()
魔法方法了,该方法定义了比较运算符 ==
的行为,重写该方法来完成我们自己的比较逻辑了!
def __eq__(self, other):
return self.__dict__ == other.__dict__
经过简单的重写后,我们的代码就可以按照预定的思路正确运行了。然而,还有一个严重的问题 …
-
和
None
进行比较当我们使用
Person
创建出来的实例和None
值进行比较的时候,此时便发生了如下错误:AttributeError: 'NoneType' object has no attribute 'name'
和 None
值进行比较时,None
被传递给了 other
,随后又在 if
语句中访问了 other
的 name
属性,但是一个 None
怎么会有 name
属性呢?这也是我们代码报错的原因,明白原因后,我们便开始继续改造代码:
def __eq__(self, other):
if isinstance(other, Person): # 判断 other 是否为Person类实例化的对象
if self.name == other.name and self.gender == other.gender: # 若是, 在进行判断
return True
else:
return False
else:
return NotImplemented
return NotImplemented
作用:此时会向 python解释器发出一个信号, 当前无法进行比较, 请尝试其他可行方法
此处解释器 会调用 父类(object)中
__eq__
方法进行比较
__ne__ 方法
除了上边的 问题外 ,还有一点需要注意,当我们仅仅实现了 __eq__
方法,却没有实现 __ne__
方法时,如果我们进行 !=
判断,那么默认会委托给 __eq__()
并对结果取反,为避免出现意外的问题,建议同时 重写 eq
和 ne
两个方法