为什么Python的bool内置函数只能查看类级别的__bool__方法 [英] Why does Python's bool builtin only look at the class-level __bool__ method

查看:126
本文介绍了为什么Python的bool内置函数只能查看类级别的__bool__方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

文档明确指出

当未定义此方法(__bool__)时,将调用__len__()(如果已定义),并且如果结果为非零,则将该对象视为true.如果 class 既未定义__len__()也未定义__bool__(),则其所有实例均被视为true.

When this method (__bool__) is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __bool__(), all its instances are considered true.

粗体字是我的插入词,斜体字是我的插入词,但实际上文本在这里.该类必须包含该方法的事实很容易通过

Bold is my insertion, italics is mine but the text is actually there. The fact that the class must contain the method is readily tested by

class A:
    pass

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

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

如文档所述,结果为True True.覆盖__len__会得到相同的结果:

The result is True True, as the documentation claims. Overriding __len__ yields the same result:

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

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

这完全按照文档要求的那样工作.但是,我发现这背后的原因有点违反直觉.我知道内置的bool不会查看实例的方法,但是我不明白为什么.知道内部工作原理的人是否知道为什么只有类级别的__bool____len__方法会影响真实性,而实例级别的方法却被忽略了?

This works exactly as the documentation claims it will. However, I find the reasoning behind this to be a little counter-intuitive. I understand that the bool builtin does not look at the methods of the instance, but I do not understand why. Does someone with a knowledge of the internal workings know why only the class-level __bool__ and __len__ methods affect truthiness while instance-level methods are ignored?

推荐答案

原因是

对于自定义类,只有在对对象的类型(而不是在对象的实例字典中)进行定义的情况下,才能保证对特殊方法的隐式调用可以正常工作.

For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.

...

此行为背后的基本原理是由所有特殊对象(包括类型对象)实现的许多特殊方法,例如__hash__()__repr__().如果这些方法的隐式查找使用常规查找过程,则在对类型对象本身进行调用时它们将失败.

The rationale behind this behaviour lies with a number of special methods such as __hash__() and __repr__() that are implemented by all objects, including type objects. If the implicit lookup of these methods used the conventional lookup process, they would fail when invoked on the type object itself.

...

除了出于正确性的考虑绕过任何实例属性之外,隐式特殊方法查找通常还绕过__getattribute__()方法,甚至是对象的元类.

In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the __getattribute__() method even of the object’s metaclass.

...

以这种方式绕过__getattribute__()机器为解释器中的速度优化提供了很大的空间,其代价是在处理特殊方法时需要一定的灵活性(必须在类对象本身上设置特殊方法,以便能够始终由解释程序调用).

Bypassing the __getattribute__() machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method must be set on the class object itself in order to be consistently invoked by the interpreter).

这篇关于为什么Python的bool内置函数只能查看类级别的__bool__方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆