[英]Why is this python class instance hashable?
This is pertaining to python 2.x 这与python 2.x有关
In the following class, if we subclass " object ", I understand the methods are inherited in the derived class Foo which includes __hash__
(can see this by printing dir(Foo() ) 在下面的类中,如果我们继承“ object ”,我理解这些方法是在包含
__hash__
的派生类Foo中继承的(可以通过__hash__
dir(Foo())看到这个
Hence calling hash(Foo()) calls the magic method __hash__
and gives us a hash value. 因此调用hash(Foo())调用魔术方法
__hash__
并给我们一个哈希值。
However, if we don't subclass " object ", resulting in dir(Foo()) not listing out the __hash__
method, so then why do we still get a hash value in python2? 但是,如果我们没有子类“ object ”,导致dir(Foo())没有列出
__hash__
方法,那么为什么我们仍然在python2中得到一个哈希值?
I believe in python3 this problem has been addressed since the methods from the 我相信python3这个问题已经解决了以来的方法 "object*" class are inherited by default.
默认情况下, “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
Old-style classes are weird. 旧式的课很奇怪。 Officially, instances of old-style classes aren't wholly instances of their class, they're all instances of type
instance
. 正式地说,旧式类的实例并不是它们类的完全实例,它们都是类型
instance
。 The instance
type defines __hash__
( tp_hash
is the C level slot that's equivalent to __hash__
for C defined types), so even though it's not defined on your instance directly, nor on the class that created it, it finds __hash__
on the instance
type itself through weird and terrible magic (actually, the magic is in how it manages to use your class's features at all, given that its type is instance
). instance
类型定义了__hash__
( tp_hash
是C级槽,相当于C定义类型的__hash__
),所以即使它没有直接在你的实例上定义,也没有在创建它的类上定义,它通过instance
类型自身找到__hash__
奇怪而可怕的魔法(实际上,神奇的是它如何设法使用你的类的功能,因为它的类型是instance
)。
You can see this in the interactive interpreter: 您可以在交互式解释器中看到:
>>> 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>
This works even though the instance itself can't see __hash__
because "special methods" (those documented special methods that begin and end with double underscores) are looked up on the type, not the instance, so __hash__
is found on instance
itself. 即使实例本身看不到
__hash__
这也__hash__
因为“特殊方法”(那些以双下划线开头和结尾的特殊方法)会在类型而不是实例上查找,因此在instance
本身上可以找到__hash__
。 At the C level, hash(x)
is doing the equivalent of type(x).__hash__(x)
(it's a little more complicated because it won't use the default __hash__
implementation if __eq__
has a custom definition, but that's the general idea). 在C级别,
hash(x)
正在执行type(x).__hash__(x)
(它有点复杂,因为如果__eq__
有自定义定义它不会使用默认的__hash__
实现,但这是一般的理念)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.