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 与实例 / 类 / 父类优先级),带你彻底打通面向对象任督二脉!

相关推荐
CTA量化套保2 小时前
期货量化临期合约还能不能做:程序化到期禁开与强平写法
python·区块链
Thomas_YXQ2 小时前
Unity3D Addressable 深度优化热更性能消耗
开发语言·3d·unity·微信
aini_lovee2 小时前
C# 快递单打印系统(万能套打系统)
开发语言·c#
量化君也2 小时前
快速入门量化交易都要学些什么?
大数据·人工智能·python·算法·金融
吴卫斌2 小时前
行业ETF轮动策略实战(二):精选候选池——打造你的赛道武器库
大数据·python·股票·量化交易
天启HTTP2 小时前
开启全局代理后网络变慢,问题出在哪
开发语言·前端·网络·tcp/ip·php
Tbisnic2 小时前
AI大模型学习 第十天:让程序“指挥”大模型 —— 从对话到工具调用
人工智能·python·ai·大模型·react·cot·提示词工程
丑过三八线2 小时前
Runc 深度解析:从原理到实操
java·linux·开发语言·docker·容器·rpc