Python变量是对象引用的标签而非存储容器,赋值即绑定标签到对象;可变对象可就地修改(id不变),不可变对象所有“修改”均创建新对象;函数传参是对象引用副本,影响取决于是否就地修改。

Python中变量不是盒子,而是标签——它不存储数据本身,而是指向内存中某个对象的引用。理解这一点,才能真正看懂赋值、函数传参、可变/不可变类型的行为差异。
变量赋值 = 绑定标签到对象
执行 a = 100 时,Python 做了三件事:创建整数对象 100(如果尚不存在),在内存中分配地址,再把名字 a 绑定到该地址。变量名本身不占“存储空间”,只是引用的别名。
- 多个变量可绑定同一对象:a = 100; b = a → a 和 b 指向同一个整数对象
- 重新赋值只是改绑:a = 200 后,a 指向新对象,b 仍指向原 100
- id() 可查看对象内存地址,is 操作符判断是否为同一对象
可变对象 vs 不可变对象:关键在“能否就地修改”
不可变对象(如 int、str、tuple)一旦创建,内容无法更改。所有“修改”操作(如 +=、s.upper())实际是新建对象并重绑变量。
可变对象(如 list、dict、set)允许就地修改内容,不改变对象身份(id 不变)。
立即学习“Python免费学习笔记(深入)”;
- lst = [1, 2]; lst.append(3) → lst 仍指向原列表对象,只是内容变了
- s = "abc"; s += "d" → 创建新字符串对象,s 绑定到新地址
- 函数内修改传入的列表会影响外部;但对传入的整数重新赋值不会影响外部变量
函数参数传递:始终是“对象引用的传递”
Python没有“传值”或“传引用”的严格分类,而是统一为“传递对象引用的副本”。也就是说,函数收到的是原始引用的一个拷贝,它和调用方变量指向同一对象。
- 若函数内对可变对象调用就地方法(如 .append()),外部可见变化
- 若函数内对参数重新赋值(如 data = [9,9]),只是让形参指向新对象,不影响实参绑定
- 想避免意外修改,可显式传副本:func(lst.copy()) 或 func(lst[:])
常见陷阱与应对建议
默认参数为可变对象(如 def func(items=[]))是高频坑:该列表对象在函数定义时创建,后续每次调用都复用同一对象,导致“累积效应”。
- 正确写法:def func(items=None): items = items or [] 或 items = items if items is not None else []
- 使用 is 判断 None,不用 ==(因 None 是单例)
- 检查变量是否指向同一对象,优先用 is;比较值相等,用 ==










