You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

类中继承自同一方法的两个实例方法为何存在差异?

为何继承自同一方法的两个类方法在实例中存在差异?

嘿,这个问题其实挺戳中面向对象编程里一个容易被忽略的细节——尤其是在Python这类动态语言里!我来给你拆解一下最常见的原因:

核心原因:实例方法的「绑定机制」

咱们先举个你可能遇到的典型场景:

class Parent:
    def my_method(self):
        print("来自父类的方法")

class Child(Parent):
    # 子类把父类的同一个方法赋值给两个不同的属性
    method_a = Parent.my_method
    method_b = Parent.my_method

当你实例化Child并检查这两个方法是否相同时,会发现:

child = Child()
print(child.method_a is child.method_b)  # 输出 False!

这是因为:

  • Parent.my_method本身是一个未绑定的函数对象(没有和任何实例关联)。
  • 当你通过实例访问method_a或method_b时,Python会自动把这个函数包装成一个绑定方法对象——这个对象会把当前实例和原函数绑定在一起,方便调用时自动传入self参数。
  • 关键是:每次访问都会生成一个新的绑定方法实例,哪怕它们包装的是同一个底层函数。

如果你想验证底层函数其实是同一个,可以直接看绑定方法的__func__属性:

print(child.method_a.__func__ is child.method_b.__func__)  # 输出 True!

其他可能的场景

除了绑定机制,还有几种情况也会导致这种差异:

  • 方法被二次包装:如果子类对其中一个方法做了额外的包装(比如用lambda、自定义装饰器),那它就不再是原方法的引用了:
    class Child(Parent):
        method_a = Parent.my_method
        method_b = lambda self: Parent.my_method(self)  # 新的lambda函数
    
    这时候method_a和method_b的底层函数完全不同,实例中自然也不一样。
  • 静态/类方法的例外:如果原方法是@staticmethod或@classmethod,那通过实例访问时不会生成绑定方法,直接返回原对象,所以两个属性会指向同一个东西:
    class Parent:
        @staticmethod
        def static_method():
            print("静态方法")
    
    class Child(Parent):
        s1 = Parent.static_method
        s2 = Parent.static_method
    
    child = Child()
    print(child.s1 is child.s2)  # 输出 True
    

总结

简单来说:

  • 实例方法通过实例访问时,每次都会生成新的绑定方法对象,导致is判断为False,但底层函数是同一个。
  • 静态/类方法不会触发绑定机制,所以引用保持一致。
  • 如果方法被二次包装,那底层函数本身就变了,差异更明显。

内容的提问来源于stack exchange,提问作者ansavchenco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:34:52