提问人:planetp 提问时间:11/13/2019 最后编辑:Chris_Randsplanetp 更新时间:11/13/2019 访问量:203
在 3.8 中比较对象方法会导致不同的结果
Comparing object methods leads to different results in 3.8
问:
考虑这个简单的类:
class A:
def method(self): pass
def __eq__(self, other): return True
现在,如果我创建该类的两个实例并比较它们的属性,我在 Python 3.7 和 3.8 中得到不同的结果:'method'
meth1 = A().method
meth2 = A().method
print(meth1 == meth2) # True in 3.7, False in 3.8
这是怎么回事?为什么这些方法在 3.7 中相等,但在 3.8 中不相等?这与什么有关?__eq__
答:
6赞
MSeifert
11/13/2019
#1
发生的事情是基于问题 16171610 的提交(以及关于 python-dev 的讨论)。
通过这些(选定的)评论:
在我看来,两个不同实例的实例方法是否相等取决于实例的相等性,这似乎是不合逻辑的。
其次
总而言之,我认为这部分是一个意外 并且从未设计过;
和
我认为实例的相等性测试意义不大 方法考虑了实例的相等性。恕我直言,这个 行为不符合无意外原则。这 正确的行为(当然,恕我直言)只是实例方法 比较等于同一实例的相同实例方法,其中 “同一实例”基于“is”而不是“==”。
和
此更改可以被视为错误修复,但由于它可能会破坏用户代码(不太可能),因此仅在 3.8 中合并它并作为新功能公开可能更安全。
因此,这似乎被认为是一个错误修复/功能,因为绑定方法只有在绑定在同一实例上时才应该相等,而不是当实例被认为是相等时才应该相等。在 Python <= 3.7 中,绑定方法 equality 调用实例的等效项(从而调用 your ),而在 Python 3.8 中,它会检查 .instance1 == instance2
__eq__
instance1 is instance2
相应的更新日志项可以在“Python 3.8.0 alpha 1”部分中找到 - 这是一个很长的项目列表,所以我在这里包含了一个副本:
- bpo-1617161:实例(内置类的方法)的哈希值现在取决于__self__标识的哈希值,而不是其值。和实例(用户定义类的方法和内置类的一些方法,如)的哈希和相等现在依赖于__self__的标识的哈希和相等,而不是它的值。 实例不再支持排序。
BuiltinMethodType
ModuleType
MethodWrapperType
str.__add__
MethodWrapperType
评论
1赞
Tom Dalton
11/13/2019
关于python-dev的讨论非常有趣,感谢您提供这个出色而富有启发性的答案:-)
评论
A
__eq__
==
function.__eq__
__eq__
A
__eq__
A.method.__eq__
__eq__
False