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

Python子类C实例c.x为何输出dog而非lemon,及实例指向全局帧问题求助

x = "dog"

class A:
    x = "cat"

class B(A):
    x = "ferret"

    def __init__(self):
        self.x = x

class C(B):
    x = "lemon"

c = C()
a = A()

print(f"{c.x = }")  # 输出 "dog"
print(f"{a.x = }")  # 输出 "cat"

为什么c.x输出为dog而非lemon

C类没有自定义__init__方法,实例化C()时会自动调用父类B的__init__方法。
核心逻辑在B的__init__赋值语句self.x = x:等号右侧的x没有加self.或者类前缀,Python解析变量会按照「方法本地作用域→外层作用域」的顺序查找:

  • __init__方法内部没有定义本地变量x
  • Python的类块不会为内部的方法创建嵌套作用域,方法的外层作用域直接是模块全局作用域,因此这里的x会直接取全局定义的x = "dog"

赋值完成后,C类实例就有了实例属性x,值为dog。而Python访问属性的优先级是:实例属性 > 所属类的类属性 > 父类的类属性,所以c.x会直接返回实例上的dog,不会查找C类定义的类属性lemon。

虚线框内的self代表什么

self就是你实例化得到的C类实例对象,也就是代码里变量c指向的那个对象。

为什么self的父帧是全局帧

这里的父帧指的是B的__init__方法执行时的外层作用域:Python中类内部定义的方法,其外层作用域是方法定义所在的模块全局作用域,而非类的作用域。所以__init__里查找变量x时最终会落到全局帧,给self赋值的x属性值就来自全局帧的dog。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 11:15:03