猴子补丁后bool(x)与x.__bool__()结果相反的原因探究
实例猴子补丁__bool__后bool()调用不生效的原因分析
问题描述
对Person类的实例bob的__bool__方法做猴子补丁后,直接调用bob.__bool__()返回True,但调用bool(bob)却仍然返回False,两者结果相反。请问该行为的原因是什么?属于语言bug还是特性?
测试代码
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Define class # class Person: def __bool__(self): return False # Create instance # bob = Person() # Call test methods # print("- Before monkey patching -") print("Using __bool__(): ", bob.__bool__()) # False print("Using bool(): ", bool(bob)) # False # Patch # def always_true(x): return True bob.__bool__ = always_true.__get__(bob, bob.__class__) # Call test methods # print("- After monkey patching -") print("Using __bool__(): ", bob.__bool__()) # True print("Using bool(): ", bool(bob)) # False
Python 3.12运行输出
- Before monkey patching - Using __bool__(): False Using bool(): False - After monkey patching - Using __bool__(): True Using bool(): False
注:使用from types import MethodType方式补丁也会得到相同结果。
原因分析
这是Python的特性,不是bug。核心原因在于Python对特殊方法(双下划线包裹的方法,如__bool__、__str__)的查找机制:
- 调用内置函数
bool(bob)时,Python会直接在bob的类(即Person)的命名空间中查找__bool__方法,不会去实例自身的属性中查找。所以哪怕给实例bob绑定了新的__bool__方法,bool()调用依然会使用类中定义的原始方法,返回False。 - 直接调用
bob.__bool__()时,是直接访问实例bob的__bool__属性,这时候会执行补丁上去的方法,所以返回True。
这种设计是为了保证内置函数行为的一致性和性能,避免实例层面的随意修改破坏语言的基础逻辑。
内容的提问来源于stack exchange,提问作者xApple
相关产品推荐
相关产品推荐

