为什么Python内置的bool仅查看类级__bool__方法

时间:2017-02-09 20:39:04

标签: python truthiness

documentation明确指出

  

如果未定义此方法__bool__,则会调用__len__()(如果已定义),如果对象的结果非零,则认为该对象为true。如果既未定义__len__()也未定义__bool__(),则其所有实例均视为true。

Bold是我的插入,斜体是我的,但文本实际上就在那里。

可以轻松测试类必须包含该方法的事实
class A:
    pass

a = A()
a.__bool__ = (lamda self: False).__get__(a, type(a))

print(bool(A()), bool(a))

结果是True True,正如文档所声称的那样。覆盖__len__会产生相同的结果:

b = A()
b.__len__ = (lambda self: 0).__get__(b, type(b))

print(bool(A()), bool(b))

这与文档声称的完全相同。但是,我发现这背后的推理有点违反直觉。我知道bool内置函数不会查看实例的方法,但我不明白为什么。知道内部工作原理的人是否知道为什么只有类级别__bool____len__方法会影响真实性而忽略实例级方法?

1 个答案:

答案 0 :(得分:1)

原因是how special methods are looked up

  

对于自定义类,只有在对象类型上定义的特殊方法的隐式调用才能保证正常工作,而不是在对象的实例字典中。

...

  

这种行为背后的基本原理在于许多特殊方法,例如__hash__()__repr__(),它们由所有对象实现,包括类型对象。如果这些方法的隐式查找使用了传统的查找过程,则在类型对象本身上调用它们时会失败。

...

  

除了为了正确性而绕过任何实例属性之外,隐式特殊方法查找通常也会绕过__getattribute__()方法,甚至是对象的元类。

...

  

以这种方式绕过__getattribute__()机制为解释器内的速度优化提供了很大的空间,代价是处理特殊方法的一些灵活性(必须在类对象本身上按顺序设置特殊方法由翻译一致地调用。)