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

下一篇我们继续深入:Python 属性查找的完整链路(MRO 与实例 / 类 / 父类优先级),带你彻底打通面向对象任督二脉!