pla*_*etp 5 python comparison equality python-3.7 python-3.8
考虑这个简单的类:
class A:
def method(self): pass
def __eq__(self, other): return True
Run Code Online (Sandbox Code Playgroud)
现在,如果我创建类的两个实例并比较它们的'method'属性,我会在 Python 3.7 和 3.8 中得到不同的结果:
meth1 = A().method
meth2 = A().method
print(meth1 == meth2) # True in 3.7, False in 3.8
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?为什么方法在 3.7 中相等但在 3.8 中不相等?这与什么有关系__eq__?
发生的事情是基于问题 16171610 的提交(以及关于 python-dev 的讨论)。
有了这些(选定的)评论:
在我看来,两个不同实例的实例方法是否相等取决于实例的相等性,这似乎不合逻辑。
其次是
总而言之,我认为这部分是一个意外,从未设计过;
和
我认为实例方法的相等性测试将实例的相等性考虑在内是没有意义的。恕我直言,这种行为不符合不出意外的原则。正确的行为(当然再次恕我直言)是实例方法只比较等于相同实例的相同实例方法,其中“相同实例”基于“是”而不是“==”。
和
此更改可被视为错误修复,但由于它可能会破坏用户代码(不太可能),因此仅在 3.8 中合并它并作为新功能公开可能更安全。
所以这似乎被认为是一个错误修复/功能,因为绑定方法只有在它们被绑定在同一个实例上时才应该是相等的,而不是如果实例被认为是相等的。在 Python <= 3.7 中,绑定方法相等调用实例的等价物instance1 == instance2(因此调用 your __eq__),而在 Python 3.8 中它检查 if instance1 is instance2。
相应的变更日志项目可以在“Python 3.8.0 alpha 1”部分找到- 这是一个很长的项目列表,所以我在这里包含了一个副本:
- bpo-1617161:
BuiltinMethodType实例的散列(内置类的方法)现在取决于__self__的身份的散列而不是它的值。ModuleType和MethodWrapperType实例的散列和相等性(用户定义类的方法和内置类的一些方法,如str.__add__)现在取决于__self__的身份的散列和相等性,而不是它的值。MethodWrapperType实例不再支持排序。