python - 为什么这个 python 类实例是可哈希的?

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

这与 python 2.x 有关

在下面的类中,如果我们子类化“object”,我知道这些方法是在包含 __hash__ 的派生类 Foo 中继承的(可以通过打印 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 类型的实例。 The instance type defines __hash__ (tp_hash 是 C 级槽,相当于 C 定义类型的 __hash__),所以即使它没有直接在您的实例上定义,也没有在创建它的类上定义,它通过奇怪而可怕的魔法在 instance 类型上找到 __hash__ (实际上,魔法在于它如何设法使用你的类的特性,因为它的类型是实例).

您可以在交互式解释器中看到这一点:

>>> 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 本身上找到的。在 C 级,hash(x) is doing the equivalent of type(x).__hash__(x) (它有点复杂,因为如果 __eq__ 有自定义定义,它不会使用默认的 __hash__ 实现,但这是一般的想法)。

关于python - 为什么这个 python 类实例是可哈希的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46229185/

相关文章:

python - 结合 Mechanize 浏览器和 Selenium

C++链表节点存储通用对象

python - 链接问题将应用程序引擎的外壳应用程序嵌入我自己的应用程序中,以帮助编码

Python-twitter api.VerifyCredentials() 返回 none

python - Sci-Kit 机器学习程序的结果代表什么?

python - 具有许多参数的对象的工厂方法

java - 为什么 java.lang.Object 不是抽象的?

python - 有没有办法在不启动服务器(可能作为库)的情况下使用 postgresql?

Python Curses - 模块 'curses' 没有属性 'LINES'

python str() 函数结果不同于 __str__() 函数的结果