列表的in操作符为何未调用Person类的__eq__方法?
Python中
in操作符的引用优先逻辑解析 核心原因
Python的容器(比如list)在执行in成员检查时,会遵循引用优先的判断逻辑:
- 首先检查目标对象与容器内元素是否为同一个引用(即
x is y判断),如果是,直接判定为存在,无需调用自定义的__eq__方法; - 只有当引用不相等时,才会调用对象的
__eq__方法进行值相等的判断。
代码场景拆解
回到你的代码:
print(p in pc)未调用__eq__的原因
你创建的p对象被直接传入PersonCollection的初始化列表,pc._data里的第一个元素就是p本身(引用完全一致)。当执行p in self._data时,Python通过is判断发现引用相同,直接返回True,跳过了__eq__的调用。print(p2 in pc)调用__eq__的可能场景
按照你给出的代码,p2同样是直接加入pc._data的对象,理论上也应该触发引用相等判断而不调用__eq__。如果实际运行中出现了调用__eq__的情况,大概率是代码存在隐性差异:- 比如初始化
PersonCollection时,传入的是Person("Person2")而非变量p2(即创建了另一个同名但不同引用的Person对象); - 或者在后续代码中对
p2进行了重新赋值,导致p2的引用发生了变化。
- 比如初始化
为什么优先用引用相等而非自定义__eq__?
Python设计时优先使用引用相等,是出于性能优化的考虑:引用判断是直接的内存地址比对,速度远快于可能包含复杂逻辑的__eq__方法。只有当引用不匹配时,才会降级到值相等判断,兼顾正确性和性能。
内容的提问来源于stack exchange,提问作者jensa
相关产品推荐
相关产品推荐

