为什么这个python类实例可以使用?

时间:2017-09-14 22:36:25

标签: python python-2.7 oop hash python-2.x

这与python 2.x有关。

在下面的类中,如果我们继承" object ",我理解这些方法是在包含{{的派生类Foo中继承的。 1}}(可以通过打印dir(Foo())

来看到这一点

因此调用hash(Foo())调用魔术方法__hash__并给我们一个哈希值。

但是,如果我们没有" object ",导致dir(Foo())没有列出{ {1}}方法,那么为什么我们仍然在python2中得到一个哈希值?

我相信python3已经解决了这个问题,因为来自 " object *" 类的方法是默认继承。

__hash__

1 个答案:

答案 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}一般的想法。