You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浅拷贝与深拷贝的对象引用及修改行为差异疑问

浅拷贝与深拷贝的对象引用问题解析

一、浅拷贝的行为差异原因

先看你的浅拷贝代码:

foo = [1, 2, []] 
bar = foo.copy() 
print(foo[0] is bar[0])  # True
print(foo[2] is bar[2])  # True

没错,foo[0]和bar[0]确实引用同一个整数对象,foo[2]和bar[2]也引用同一个列表对象。但你后续的两个操作本质完全不同:

  1. bar[0] = 0:重新赋值引用
    这个操作不是修改原来的整数对象(整数是不可变类型,根本没法修改),而是把bar这个列表的第0个位置,从原来指向整数1的引用,改成指向新的整数0。foo列表的第0个位置依然指向原来的1,所以foo输出还是[1, 2, []]。

  2. bar[-1].append(3):修改引用的对象本身
    bar[-1]指向的是和foo[-1]同一个列表对象,列表是可变类型,append操作是直接修改这个列表的内容。既然两个变量都指向同一个列表,那两边都会看到修改后的结果,所以foo输出变成[1, 2, [3]]。

二、深拷贝的引用差异原因

再看深拷贝代码:

import copy
foo = [1, 2, []] 
bar = copy.deepcopy(foo)
print(foo[0] is bar[0])  # True
print(foo[2] is bar[2])  # False
  • 关于foo[0] is bar[0]为True:Python对**小整数(范围通常是-5到256)**有缓存机制,会复用同一个对象实例,所以1这个整数在foo和bar里是同一个引用。如果换成一个超出这个范围的整数,比如foo = [1000, 2, []],再深拷贝的话,foo[0] is bar[0]就会是False。
  • 关于foo[2] is bar[2]为False:深拷贝会递归地拷贝所有嵌套的可变对象,这里foo[2]是一个列表,deepcopy会创建一个全新的列表对象,所以bar[2]和foo[2]是完全独立的两个对象,自然is判断为False。

内容的提问来源于stack exchange,提问作者Aaron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 05:22:44