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

父类实例变量被子类覆盖:如何让父类方法输出原变量值?

class Foo:
    def __init__(self):
        self.model = "A"

    def create(self):
        print(f"Model in class {self.model}")


class Bar(Foo):
    def __init__(self):
        super().__init__()
        self.model = "B"

    def save(self):
        super().create()
        print(f"Model in class Bar {self.model}")


bar = Bar()
bar.save()

输出:

Model in class Foo B
Model in class Bar B

问题

为何父类Foo中的实例变量model会被子类覆盖?这是正常预期行为吗?我希望父类方法执行时输出“A”,当前代码存在什么问题?


解答

  1. 父类实例变量被覆盖的原因
    Python中子类实例和父类方法共享同一个实例属性空间。你的Bar类__init__方法先调用super().__init__(),给实例的model赋值为"A",紧接着又将self.model改为"B"——这直接修改了同一个实例的属性值。当父类create方法执行时,它访问的是当前Bar实例的model属性,自然就是已经被修改后的"B"。

  2. 是否属于正常预期行为
    是的,这完全符合Python的属性查找规则。实例属性是全局绑定在实例上的,父类方法访问的也是当前实例的属性,所以子类对实例属性的修改会被父类方法感知到。

  3. 当前代码的问题与解决思路
    当前代码的核心矛盾是:你在子类初始化时覆盖了父类设置的实例属性,却期望父类方法访问未修改前的值。要实现父类方法输出"A",可以参考以下几种方案:

  • 调整赋值顺序:把self.model = "B"移到调用父类方法之后。比如在Bar的save方法里,先执行super().create(),再给self.model赋值,这样父类方法执行时用的还是初始的"A"。
  • 改用类属性:如果父类的model不需要每个实例单独定制,可以将其设为类属性,让父类方法直接访问类本身的属性,不受子类实例属性影响:
    class Foo:
        model = "A"
        def create(self):
            print(f"Model in class {Foo.model}")
    
  • 子类使用独立属性名:子类避免使用model作为属性名,改用bar_model这类专属名称,从根源上避免属性冲突。
  • 父类保留初始属性:在父类__init__中把初始值存入独立属性(比如self._base_model = "A"),然后create方法输出这个属性,子类修改model就不会影响父类方法的输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:15:34