从Python 文档中“数据模型”一章的“新式类的特殊方法查找”部分(粗体强调我的):
对于新式类,特殊方法的隐式调用只有在对象类型上定义时才能保证正常工作,而不是在对象的实例字典中。这种行为是以下代码引发异常的原因(与旧式类的等效示例不同):
>>> class C(object): ... pass ... >>> c = C() >>> c.__len__ = lambda: 5 >>> len(c) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'C' has no len()
这种行为背后的基本原理在于许多特殊方法,例如
__hash__()
和__repr__()
由所有对象实现,包括类型对象。如果这些方法的隐式查找使用常规查找过程,则在类型对象本身上调用它们时会失败:>>> 1 .__hash__() == hash(1) True >>> int.__hash__() == hash(int) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: descriptor ’__hash__’ of ’int’ object needs an argument
以这种方式错误地尝试调用类的未绑定方法有时被称为“元类混淆”,并且可以通过在查找特殊方法时绕过实例来避免:
>>> type(1).__hash__(1) == hash(1) True >>> type(int).__hash__(int) == hash(int) True
粗体字我听不懂……</p>