python中“硬绑定”指obj.method访问瞬间生成的bound method对象,其__self__和__func__固化不变,与后续mro变更无关;mro仅影响方法查找过程,不改变已绑定方法的行为。

这个问题核心不在“bind”,而在 Python 的方法绑定机制与多重继承的 MRO(Method Resolution Order)共同作用下的行为逻辑。Python 里没有 JavaScript 那种显式的 bind 方法,所谓“硬绑定实例方法”实际是指:一个已绑定到具体实例的方法对象(如 obj.method),在被赋值、传递或调用时,其 self 是否稳定、是否受继承链干扰。
绑定方法的本质是闭包,不是动态查找
当你写 obj.method,Python 立即生成一个 bound method 对象,它内部持有一个对 obj 的强引用和对定义该方法的函数的引用。这个绑定发生在访问瞬间,与后续类结构变化、MRO 调整完全无关。
- 即使你后来修改了类的继承关系(比如动态增删父类),已存在的 bound method 不会重新解析;它的
self和底层函数都是确定的 - 它不“知道”自己来自哪个类——只知道自己是“
obj上名为method的函数” - 所以不存在“虚拟继承链下绑定失效”或“需要重新 bind”的问题
多重多级继承影响的是方法查找,不是已有绑定
MRO 决定的是:当访问 obj.method 时,Python 去哪找这个 method。一旦找到并完成绑定,结果就固化了。例如:
class A: def f(self): return 'A'class B(A): passclass C(B, object): pass-
obj = C()→obj.f绑定到A.f,因为C.__mro__是(C, B, A, object) - 哪怕你之后给
B动态加一个f,已有的obj.f仍调用A.f;新创建的实例才会走新 MRO
super() 与绑定方法共存时的常见误解
super() 是动态的——它每次调用都按当前实例的类和 MRO 查找下一个方法。但如果你把 super().method 的结果提前存成 bound method,它就不再动态了:
-
bound = obj.__class__.__mro__[1].method.__get__(obj, obj.__class__)—— 这是手动模拟 super 查找后硬绑定,之后调用不依赖 MRO -
bound = lambda: super(C, obj).method()—— 这仍是动态的,因为super()在 lambda 执行时才求值 - 真正“硬绑定”的只有
obj.method这种直接属性访问形式
验证绑定真实性的简单方式
想确认某个方法是不是真绑定到了目标实例,直接检查它的 __func__ 和 __self__:
bound = obj.method-
bound.__self__ is obj→ 必为True -
bound.__func__指向原始函数对象,不会因继承链改变而变 - 打印
type(bound)是<class></class>,不是function或builtin_function_or_method











