[英]Why is this python class instance hashable?
這與python 2.x有關
在下面的類中,如果我們繼承“ object ”,我理解這些方法是在包含__hash__
的派生類Foo中繼承的(可以通過__hash__
dir(Foo())看到這個
因此調用hash(Foo())調用魔術方法__hash__
並給我們一個哈希值。
但是,如果我們沒有子類“ object ”,導致dir(Foo())沒有列出__hash__
方法,那么為什么我們仍然在python2中得到一個哈希值?
我相信python3這個問題已經解決了以來的方法 默認情況下, “object *”類是繼承的。
#class Foo(object) Works since __hash__ is available in the base class
class Foo: #Why does this work?
def __init__(self):
self.x = None
a = Foo()
print dir(a) # No __hash__ magic method
print hash(a)
# Expecting an error like non-hashable or __hash__ not implemented
# or something similar
舊式的課很奇怪。 正式地說,舊式類的實例並不是它們類的完全實例,它們都是類型instance
。 instance
類型定義了__hash__
( tp_hash
是C級槽,相當於C定義類型的__hash__
),所以即使它沒有直接在你的實例上定義,也沒有在創建它的類上定義,它通過instance
類型自身找到__hash__
奇怪而可怕的魔法(實際上,神奇的是它如何設法使用你的類的功能,因為它的類型是instance
)。
您可以在交互式解釋器中看到:
>>> class Foo: pass
>>> Foo().__hash__ # Same basic error for Foo.__hash__ too
AttributeError Traceback (most recent call last)
...
----> 1 Foo().__hash__
AttributeError: Foo instance has no attribute '__hash__'
>>> type(Foo())
<type 'instance'>
>>> type(Foo()).__hash__
<slot wrapper '__hash__' of 'instance' objects>
即使實例本身看不到__hash__
這也__hash__
因為“特殊方法”(那些以雙下划線開頭和結尾的特殊方法)會在類型而不是實例上查找,因此在instance
本身上可以找到__hash__
。 在C級別, hash(x)
正在執行type(x).__hash__(x)
(它有點復雜,因為如果__eq__
有自定義定義它不會使用默認的__hash__
實現,但這是一般的理念)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.