Python 高级编程 019:类变量与实例变量彻底解析

Python 高级编程 019:类变量与实例变量彻底解析

在 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 面向对象的世界里:

  • 类变量是「公共池」,大家共用,一改全改;

  • 实例变量是「私人抽屉」,各自独立,互不打扰。

只要记住两条铁律:

  1. 查找:先实例,后类

  2. 赋值:实例赋值 = 新建属性,不是修改类变量

你就彻底掌握了类变量与实例变量的核心,后续再学习属性查找顺序、自省机制,都会一通百通。

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

相关推荐
神仙别闹8 小时前
基于 C++ 实现(控制台)学生成绩管理系统
开发语言·c++
Y幽谷客9 小时前
Python加载本地大模型(Qwen3.5 8B)
python·大模型
伞伞悦读9 小时前
【第36期】Python 目录与路径详解:pathlib、文件遍历、创建、复制、移动和删除风险
开发语言·python
线上放牧人9 小时前
Windows删除图标缓存
windows·python·pyqt
qq_54702617910 小时前
Python 变量和简单数据类型
python
智搜广告11 小时前
智搜广告:科技行业AI回答优化公司如何破局
大数据·python·elasticsearch·geo
IpdataCloud11 小时前
AI智能体调用工具怎么核验来源IP?归属地、网络类型与代理风险识别(含Python代码)
数据库·python·tcp/ip
2601_9669496512 小时前
只拿到股票代码还不够:量化程序到底还需要哪些标的信息?——从数据建模开始理解股票元数据
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
蒸鱼Yuzheng12 小时前
Python 游戏测试开发怎么准备:日志解析、接口校验、并发与可维护性
自动化测试·python·测试开发·面试题·游戏测试
m0_7345717612 小时前
深入理解5g <十八>传输块tbsize的计算
开发语言·5g