
本文详解 python 类变量在继承链中的行为:当子类直接赋值修改类变量时,会创建独立属性,不再访问父类变量;而父类变量的修改则影响所有未覆盖该变量的子类。
在 Python 中,类变量(如 val = 1)属于类对象自身的命名空间。当子类未显式定义同名变量时,通过点号(.)访问该变量会触发 MRO(Method Resolution Order)查找——即沿继承链向上搜索,直到找到第一个匹配项。但关键在于:直接赋值(如 B.val = 2)不会修改父类,而是在子类 B 的命名空间中新建一个同名类变量。此时 B.val 不再“继承” A.val,而是拥有了自己的独立绑定。
以下代码清晰展示了这一机制:
class A(object):
val = 1
class B(A):
pass
class C(A):
pass
print(A.val, B.val, C.val) # 输出: 1 1 1
# 所有类均未定义 val,故都查找到 A.val
B.val = 2
print(A.val, B.val, C.val) # 输出: 1 2 1
# B.val 现在是 B 自己的属性;A.val 和 C.val 仍指向 A.val
A.val = 3
print(A.val, B.val, C.val) # 输出: 3 2 3
# 修改 A.val 影响所有未覆盖它的类(A 和 C),但 B 已拥有独立 val,不受影响⚠️ 注意事项:
- B.val = 2 是类对象 B 的属性赋值操作,等价于 setattr(B, 'val', 2),它在 B.__dict__ 中新增键值对,切断了对 A.val 的动态引用;
- C 始终未定义 val,因此 C.val 持续通过继承链解析为 A.val,随 A.val 变化而变化;
- 若需真正“同步更新”所有子类的值,应避免子类直接赋值,改用类方法或 @classmethod 统一管理,或使用可变对象(如 val = [1])——但后者易引发隐蔽副作用,不推荐作为常规方案。
✅ 总结:Python 类变量的“继承”本质是运行时名称解析,而非引用共享;赋值即屏蔽(shadowing),修改父类变量仅影响尚未屏蔽它的子类。理解这一机制,是写出可维护、可预期的面向对象代码的关键基础。
立即学习“Python免费学习笔记(深入)”;










