当__hash__和__eq__在没有参数的情况下不可调用时,Python 的字典如何将类型作为键进行管理?



Python文档规定字典键必须是可哈希的,这意味着有__hash____eq__

我试图理解在字典中使用类型作为键是如何工作的,至少在默认情况下,这两个方法都期望一个实例作为第一个参数。

考虑下面的代码及其输出:

class Apple:
pass
class Orange:
pass
lookup = {Apple: lambda: print('Apple!'), Orange: lambda: print('Orange!')}
try:
print(Apple.__hash__())
except Exception as e:
print(e)

try:
print(Apple.__eq__())
except Exception as e:
print(e)
an_apple = Apple()
an_orange = Orange()
lookup[type(an_apple)]()
lookup[type(an_orange)]()
descriptor '__hash__' of 'object' object needs an argument
descriptor '__eq__' of 'object' object needs an argument
Apple!
Orange!

dict如何获取哈希值并检查类型是否相等?

Python不查找实例中的魔法方法。它在类本身上查找它们。在您的示例中,Appletype

>>> class Apple: pass
... 
>>> hash(Apple)
5929200437980
>>> type.__hash__(Apple)
5929200437980

同样的事情发生在__eq__上。如果您尝试将魔法方法附加到实例而不是类,也可以看到这一点。

>>> class Apple:
...   def __hash__(self):
...     return 1
... 
>>> my_apple = Apple()
>>> my_apple.__hash__ = lambda: 2
>>> hash(my_apple) # 1, not 2
1
>>> my_apple.__hash__()
2
>>> Apple.__hash__(my_apple)
1

注意,Applemy_apple都在它们上面定义了__hash__,但它是类的方法被调用,而不是实例上的方法。

最新更新