这与python 2.x有关。
在下面的类中,如果我们继承" object ",我理解这些方法是在包含{{的派生类Foo中继承的。 1}}(可以通过打印dir(Foo())
来看到这一点因此调用hash(Foo())调用魔术方法__hash__
并给我们一个哈希值。
但是,如果我们没有" object ",导致dir(Foo())没有列出{ {1}}方法,那么为什么我们仍然在python2中得到一个哈希值?
我相信python3已经解决了这个问题,因为来自 " object *" 类的方法是默认继承。
__hash__
答案 0 :(得分:3)
旧式课很奇怪。正式地说,旧式课程的实例并不是他们班级的完整实例,他们都是instance
类型的所有实例。 The instance
type defines __hash__
(tp_hash
是C级别的插槽,对于C定义的类型,它等同于__hash__
),所以即使它没有直接在您的实例上定义,也没有在创建它的类中,它通过奇怪而可怕的魔法在__hash__
类型上找到instance
(实际上,神奇之处在于它如何设法使用你的类的功能,鉴于其类型为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__
,这仍然有效,因为&#34;特殊方法&#34; (那些记录的以双下划线开头和结尾的特殊方法)会在类型而不是实例上查找,因此__hash__
本身就可以找到instance
。在C级,hash(x)
is doing the equivalent of type(x).__hash__(x)
(它稍微复杂一点,因为如果__hash__
有自定义定义,它就不会使用默认的__eq__
实现,但是那个&#39}一般的想法。