python变量赋值是绑定名称到对象而非存储值,所有变量均为对象引用;不可变对象修改会创建新对象,可变对象支持原地修改;函数参数传递为对象引用,原地修改影响外部。

Python中变量赋值不是“把值存进变量”,而是“让变量指向某个对象”——这是理解Python内存行为的核心。所有变量都是对象的引用,赋值操作只是绑定名称到对象,不复制数据。
变量本质是标签,不是容器
Python里没有传统意义上的“变量存储空间”。当你写 a = 100,解释器做了三件事:创建整数对象 100(如果尚不存在)、在内存中分配该对象、再把名字 a 绑定到它。变量 a 本身不占数据空间,只是一个指向对象的标签。
- 多个变量可绑定同一对象:a = 100; b = a → a 和 b 都指向同一个整数对象
- 修改变量名只是改变绑定:a = "hello" 不影响 b,b 仍指向原来的 100
- id(a) 返回对象在内存中的唯一标识,可用来验证是否指向同一对象
可变对象与不可变对象的关键差异
赋值行为一致,但后续操作效果不同,根源在于对象是否允许原地修改:
- 不可变对象(如 int、str、tuple):一旦创建就不能改内容。任何“修改”操作(如 s += "x")实际是创建新对象并重新绑定变量
- 可变对象(如 list、dict、set):支持原地修改(如 lst.append(1))。若多个变量引用同一列表,任一变量调用原地方法,所有变量都能看到变化
- 注意:= 永远只是绑定,不会触发拷贝;想真正复制需用 .copy()、copy.deepcopy() 或切片(如 lst[:])
函数参数传递也是引用,但行为像“传对象”
Python没有“传值”或“传引用”的严格分类,而是“传对象引用”。函数内对参数的重新赋值不影响外部,但对可变对象的原地修改会影响外部:
立即学习“Python免费学习笔记(深入)”;
- def f(x): x = [99]; print(x) → 外部列表不变,因为 x = [99] 只是让形参 x 指向新列表
- def f(lst): lst.append(99) → 若传入 my_list = [1,2],调用后 my_list 变为 [1,2,99],因为 append 修改了原对象
- 安全做法:若不希望函数修改原始数据,应在函数内主动复制,如 local_lst = lst.copy()
如何观察和验证引用关系
几个实用技巧帮你看清运行时的对象连接:
- 用 id(obj) 查看对象身份,相同 id 表示同一对象
- 用 is 判断是否为同一对象(比 == 更底层),如 a is b
- 用 sys.getrefcount(obj) 查看当前有多少引用指向该对象(注意:调用本身会临时增加一次引用)
- 小整数(-5 到 256)和短字符串会被缓存,所以 a = 10; b = 10 时 a is b 为 True,但这属于优化细节,不应依赖
理解这个模型能避免常见陷阱,比如误以为赋值会复制列表、搞不清函数里修改为何影响外部、或者对 is 和 == 的混淆。它不是语法糖,而是Python运行机制的底层事实。










