基本类型赋值复制值,引用类型赋值复制地址;函数传参均为对象引用的副本,可变对象内容修改影响外部,重新赋值不影响;==比值,is比地址;需独立副本时用copy()或deepcopy()。

基本类型和引用类型在使用中最大的区别,不是“能不能改”,而是“改的时候动的是谁”。理解这一点,就能避开绝大多数常见坑。
赋值时:复制值 vs 复制地址
给变量赋值,表面看都是“=”,背后行为完全不同:
- 基本类型(int、float、bool、str、tuple)赋值,是把值完整拷贝一份,两个变量互不干扰;
- 引用类型(list、dict、set、class 实例)赋值,只是把内存地址复制过去,两个变量指向同一块数据。
例如:a = [1, 2]; b = a; b.append(3) → a 也变成 [1, 2, 3],因为没创建新列表,只加了一个元素。
函数传参时:“共享传参”不是“引用传递”
Python 没有真正的“引用传递”,所有参数都是对象引用的副本。关键看对象是否可变:
- 传入不可变对象(如 int、str),函数内重新赋值不影响外部;
- 传入可变对象(如 list、dict),函数内调用方法修改内容(如 .append()、.update()),外部会同步变化;
- 但若在函数内直接赋值(如 arr = [99]),只是让形参指向新对象,不影响实参。
判断相等时:== 和 is 的分工要清楚
== 比较的是值是否相等,is 比较的是是否为同一个对象(内存地址相同):
- 小整数(-5 到 256)和短字符串常被缓存,is 可能返回 True,但这是实现细节,不能依赖;
- 判断是否为 None,必须用 x is None,而不是 x == None;
- 检查两个列表内容是否一样,用 ==;想确认是不是同一个列表,才用 is。
需要独立副本时:别只靠赋值
直接赋值无法切断引用关系。真正需要“各管各”的时候:
- 列表浅拷贝:b = a.copy() 或 b = a[:] 或 b = list(a);
- 字典浅拷贝:d2 = d1.copy();
- 涉及嵌套结构(比如列表里还有列表),必须用 import copy; copy.deepcopy(obj);
- 切记:b = a * 1 或 b = [x for x in a] 都只是浅拷贝,对嵌套对象无效。

















