为什么我不能将 `cls.__hash__ = id` 赋值?

7

我本以为这(在Python 3.6中)可行,

class A:
    __hash__ = id
A().__hash__()

但我会得到
TypeError: id() takes exactly one argument (0 given)

令人惊讶的是,

def my_id(self):
    return id(self)
class A:
    __hash__ = my_id
A().__hash__()

正常工作。


2
这不仅仅是 __hash__。使用普通方法也会得到相同的结果。我认为作为内置函数的 id 并不完全遵循 Python 中编写的函数的规则。 - khelwood
1个回答

8

id 的类型是 builtin_function_or_method(这是内置在运行时的函数),由于实用理由(主要是优化),它不像 Python 函数一样实现了 descriptor 协议,因此 A().__hash__ 将解析为 id 函数本身,而不是对该函数进行包装的 method 对象。

对于大多数内置函数,您会观察到相同的行为,顺便说一句:

>>> type(len)
<class 'builtin_function_or_method'>
>>> len.__get__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__get__'
>>> 
>>> type(all)
<class 'builtin_function_or_method'>
>>> all.__get__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__get__'
>>> type(abs)
<class 'builtin_function_or_method'>
>>> abs.__get__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__get__'
>>> type(isinstance)
<class 'builtin_function_or_method'>
>>> isinstance.__get__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__get__'

etc...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接