当前位置:首页>python>Python变量不是盒子!一张图彻底搞懂赋值、引用和拷贝

Python变量不是盒子!一张图彻底搞懂赋值、引用和拷贝

  • 2026-09-10 12:16:14
Python变量不是盒子!一张图彻底搞懂赋值、引用和拷贝

先来做两道题,看看你能全对吗?

题目一:

a =10b = ab =20print(a)# 输出?

题目二:

a =[1,2,3]b = ab.append(4)print(a)# 输出?
答案分别是 10 和 [1, 2, 3, 4]。

为什么同样是“把 a 赋值给 b”,修改 b 后,第一个 a 没变,第二个 a 却变了?

如果你能秒懂,那这篇文章对你来说可能是复习。
如果你犹豫了,甚至答错了,那这 5 分钟,将彻底改变你对 Python 变量的认知。

一、你脑海中的“变量”可能是错的

很多初学者把变量想象成一个盒子:

  • a = 10 就是把数字 10 放进盒子 a

  • b = a 就是把盒子 a 里的东西复制一份,放进盒子 b

这个模型在大多数时候能工作,但一旦遇到列表、字典,就会翻车。
因为 Python 的变量根本不是盒子,而是“便利贴”。

便利贴模型:

  • 每个对象(比如数字 10、列表 [1,2,3])都有一块独立的内存空间

  • 变量名就是一张便利贴,贴在对象上

  • b = a 不是复制对象,而是再拿一张新便利贴,贴在同一个对象上

所以当你修改那个对象时,所有贴在上面的便利贴(变量名)都能看到变化。

二、不可变对象 vs 可变对象

为什么数字和列表表现不同?因为 Python 中的对象分两类:

① 不可变对象(int, float, str, tuple, bool)
创建后内容不能改。你每次“修改”其实是新建了一个对象,然后把标签撕下来贴到新对象上。

a =10# 对象 10,贴上 ab = a       # b 也贴在对象 10 上b =20# 新建对象 20,把 b 撕下来贴到 20 上# a 仍然贴在 10 上,所以 a 还是 10

② 可变对象(list, dict, set, 自定义类实例)
创建后内容可以原地修改,不需要新建对象。

a =[1,2,3]# 创建列表对象,贴上 ab = a         # b 也贴在这个列表上b.append(4)# 原地修改列表,所有标签都能看到变化# a 和 b 都贴在同一对象上,所以 a 也变成了 [1,2,3,4]

三、图解真相(建议你脑补或画一下)

场景一:不可变

  1. 内存中有一个对象 10,标签 a 指向它。

  2. 执行 b = a,内存中还是只有对象 10,现在多了一个标签 b 指向它。

  3. 执行 b = 20,内存中新建对象 20,然后把标签 b 移过去,a 仍然指向 10。

场景二:可变

  1. 内存中有一个列表对象 [1,2,3],标签 a 指向它。

  2. 执行 b = a,同一个列表对象,多了标签 b。

  3. 执行 b.append(4),没有新建列表,而是修改了那个列表的内部内容。a 和 b 指向的还是那个列表,所以都变了。

四、这个知识有什么用?

1. 函数传参时,小心修改外部数据

def add_item(lst):    lst.append(999)my_list =[1,2,3]add_item(my_list)print(my_list)# [1,2,3,999]  原列表被改了!

如果不希望原列表被改,传入副本:add_item(my_list.copy())。

2. 拷贝列表时要分清深浅

  • b = a.copy() 或 b = a[:] 创建的是浅拷贝——新列表,但里面的元素(如果是可变对象)仍然共享引用。

  • 如果你有嵌套列表,浅拷贝可能还不够,需要深拷贝 copy.deepcopy()。

不过对大学生来说,先掌握浅拷贝就够用了。

五、避开这 3 个常见误区

误区①:以为 = 会复制数据
真相:= 只复制引用,不复制数据。要复制数据,请用 .copy()、list() 或切片。

误区②:认为不可变对象“不能改”就等于“值不变”
其实 a = a + 1 会创建新对象,原对象没变。这并不矛盾,只是你“重新贴标签”了。

误区③:混淆 == 和 is

  • == 比较值是否相等

  • is 比较是否是同一个对象(内存地址)

a =[1,2,3]b =[1,2,3]print(a == b)# True,值一样print(a is b)# False,不是同一个对象

六、一句话记住今天的内容

Python 变量是贴在对象上的便利贴,不是存放东西的盒子。
可变对象可以原地修改,所有标签同步变化;不可变对象只能新建,原标签不受影响。

理解了这句话,你就能预测任何赋值操作的结果,再也不会被列表拷贝、函数传参搞晕了。

🎁 福利:Python 入门大礼包(限时免费领)

关注我的公众号  ,在后台回复关键词 学习 ,即可免费领取:

  • 📺 400 集 Python 零基础入门视频教程(从环境搭建到项目实战)

  • 📚 10 本 Python 经典电子书(《Python编程:从入门到实践》《流畅的Python》等)

📢 最后的最后

如果觉得有用,点个「赞」和「在看」,让更多朋友看到。

最新文章

随机文章