覆盖本质是名字绑定、引用复用或属性遮蔽三类机制:实例赋值新建同名属性遮蔽类变量;列表append同一字典引用导致数据被改;内置函数名被赋值后失去可调用性。

school 这类名字一出现在赋值语句左边,就容易触发覆盖——不是“变量被改了”,而是 Python 在实例上新建了一个同名属性,遮住了类上的 school。
这背后没有魔法,只有明确的属性查找规则和内存分配逻辑。
实例赋值会直接写入实例 __dict__
当你执行 stu1.school = "希望小学",Python 并不会去修改类的 school,而是直接在 stu1.__dict__ 里新增一个键值对 {'school': '希望小学'}。之后所有对 stu1.school 的访问都命中这个实例属性,跳过类变量。
- 类变量始终存在
Student.__dict__中,所有未显式设置school的实例(如Student("小红"))仍通过查找链拿到它 - 一旦实例自己有了
school,查找就停在实例层,不再向上找类 - 用
del stu1.school可以删掉这个遮蔽项,恢复对类变量的访问
list.append() 时字典被覆盖,本质是同一对象引用
这不是类/实例变量问题,但常被误认为“覆盖”:循环中反复 append(d),而 d 始终是同一个 dict 对象。每次修改 d['b'],所有列表元素看到的都是最新状态。
- 错误写法:
data.append(d)—— 追加的是引用,不是副本 - 安全写法:
data.append(d.copy())(浅拷贝)或data.append(dict(d)) - 嵌套字典需用
copy.deepcopy(d),否则内层仍共享引用
函数名、内置名被覆盖会导致 TypeError: 'int' object is not callable
像 set = 10 这种操作,会让名字 set 从函数变成整数。后续调用 set([1,2,3]) 就失败——因为此时 set 已不是可调用对象。
- 常见踩坑点:
str、list、dict、max、min被用作变量名 - 检查方法:
print(type(set)),若输出<class></class>就说明已被覆盖 - 修复只需重启解释器或重命名变量,比如改用
my_set
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











