Python 高级编程 019:类变量与实例变量彻底解析
- 一、先搞懂:什么是类变量?什么是实例变量?
- 1.1 类变量:归属于类的「共享资产」
- 1.2 实例变量:归属于对象的「私有资产」
- 二、属性查找规则:先实例,后类 ⬆️
- 三、最容易踩坑:修改行为完全不同!
- 3.1 用「类名」修改:真正改类变量
- 3.2 用「实例名」赋值:不是修改,是「新建」!
- 四、类变量的本质:所有实例「共享」
- 五、一张表总结,再也不会忘
- 六、最后小结 ✨
在 Python 面向对象编程里,类变量与实例变量是最基础、却最容易踩坑的知识点。很多时候代码逻辑异常、数据被意外篡改,根源都在于没分清:变量到底归属于「类」,还是归属于「实例」。
今天我们就用最通俗的语言 + 可直接运行的代码,把这两个概念掰开揉碎,让你彻底理解它们的定义、查找规则与修改行为。
一、先搞懂:什么是类变量?什么是实例变量?
1.1 类变量:归属于类的「共享资产」
类变量,直接定义在类内部、方法外部,它不属于某一个实例,而是整个类的所有实例共享的属性。
你可以把它理解为:这个类的「公共配置」「全局参数」。
classA:# 🔥 类变量:定义在类内部、方法外AA=1def__init__(self,x,y):self.x=x self.y=y1.2 实例变量:归属于对象的「私有资产」
实例变量(对象变量),定义在方法内部,并且必须以self.开头绑定到具体实例。
它是每个对象独立拥有的属性,互不干扰。
classA:AA=1def__init__(self,x,y):# 🔥 实例变量:绑定到 self(当前实例)self.x=x self.y=y一句话区分:
直接写在类里 → 类变量
带 self. → 实例变量
二、属性查找规则:先实例,后类 ⬆️
Python 查找属性有一条铁律:
从当前实例自身找 → 找不到 → 向上找类的属性 → 还找不到 → 报错!
而反过来:类绝对不会向下查找实例的属性!
我们用代码验证:
# 实例化对象a=A(2,3)# 访问实例变量(自己就有,直接返回)print(a.x)# 2print(a.y)# 3# 访问类变量(实例自己没有,向上找到类的 AA)print(a.AA)# 1# ❌ 类不能访问实例变量!# print(A.x) → 报错:type object 'A' has no attribute 'x'这就是为什么:
实例能读到类变量
但类绝对读不到实例变量
因为实例变量是绑定到具体对象的,类根本不知道它有哪些实例。
三、最容易踩坑:修改行为完全不同!
这是 90% 开发者都会混淆的点:
用「类名」修改 vs 用「实例名」修改,结果天差地别!
3.1 用「类名」修改:真正改类变量
classA:AA=1def__init__(self,x,y):self.x=x self.y=y a=A(2,3)# ✅ 用类名修改:真正修改类变量A.AA=11print(a.AA)# 11(实例共享到新值)print(A.AA)# 11(类本身已被修改)✅ 结论:
类变量一改,所有实例全部同步更新!
3.2 用「实例名」赋值:不是修改,是「新建」!
classA:AA=1def__init__(self,x,y):self.x=x self.y=y a=A(2,3)# ❌ 看起来像修改,实际是:给实例 a 新建一个实例变量 AAa.AA=100print(a.AA)# 100(实例自己有了,优先用自己的)print(A.AA)# 1(类变量纹丝不动!)🔥 核心真相:
实例。属性 = 值 → 不会修改类变量,而是给这个实例新增一个同名实例变量!
从此:
实例
a有自己的AA类
A依然保留原来的AA
两者完全独立,互不影响。
四、类变量的本质:所有实例「共享」
再看一个例子,你会更通透:
classA:AA=1def__init__(self,x,y):self.x=x self.y=y# 实例化两个对象a=A(2,3)b=A(4,5)# 统一修改类变量A.AA=11print(a.AA)# 11print(b.AA)# 11print(A.AA)# 11✅ 最终结论:
类变量是全局共享的,一个修改,全部生效;
实例变量是独立私有的,各用各的,互不干扰。
五、一张表总结,再也不会忘
| 维度 | 类变量 | 实例变量 |
|---|---|---|
| 定义位置 | 类内部、方法外 | 方法内部,带self. |
| 归属 | 整个类,所有实例共享 | 单个实例,独立私有 |
| 查找顺序 | 实例找不到时向上查找 | 优先查找自身 |
| 修改方式 | 类名。属性 = 值 | 实例名。属性 = 值 |
| 实例赋值 | 不会改类,会新建实例属性 | 直接修改自身属性 |
| 影响范围 | 所有实例同步生效 | 只影响当前实例 |
六、最后小结 ✨
在 Python 面向对象的世界里:
类变量是「公共池」,大家共用,一改全改;
实例变量是「私人抽屉」,各自独立,互不打扰。
只要记住两条铁律:
查找:先实例,后类
赋值:实例赋值 = 新建属性,不是修改类变量
你就彻底掌握了类变量与实例变量的核心,后续再学习属性查找顺序、自省机制,都会一通百通。
下一篇我们继续深入:Python 属性查找的完整链路(MRO 与实例 / 类 / 父类优先级),带你彻底打通面向对象任督二脉!