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

Python中连续调用list.copy()传入print时ID相同的原因与疑问

问题解答

1. 触发原因:临时对象的内存复用

这种现象本质是Python垃圾回收机制对无引用临时对象的内存复用优化:

  • 执行id(a.copy())时,a.copy()生成的列表副本是个临时对象——它没有被赋值给任何变量,也没有其他引用指向它。一旦id()获取完它的内存地址,这个对象就失去了所有引用,Python会立刻回收它占用的内存空间。
  • 紧接着执行第二个id(a.copy())时,新创建的列表副本会复用刚刚被释放的内存地址,因此两次输出的ID完全相同。

其他测试场景不会出现该现象的原因:

  • 赋值给变量(b, c = a.copy(), a.copy()):两个副本被变量持有引用,对象不会被立即回收,因此占用不同内存地址。
  • 传入自定义函数:函数参数会持有对象的引用,两个副本在函数执行期间同时存在,ID自然不同。
  • a.copy() is a.copy():这个表达式会先计算左右两边的副本,两个对象会同时存在(因为要完成is比较),所以它们的内存地址不同,结果为False。

2. 潜在风险与其他复现方式

潜在bug可能性

正常编程场景下几乎不会引发bug:

  • 这种内存复用仅发生在无引用的临时对象上,只要你将对象赋值给变量、存入容器或用其他方式持有引用,对象就不会被立即回收,ID会保持唯一。
  • 只有当你错误地用id()的结果作为对象的唯一标识(比如用ID做缓存键)时,才可能出现逻辑错误——不同对象可能在不同时间复用同一个内存地址。但Python中判断对象是否为同一个应该用is,判断值相等用==,用id()做判断本身就是不规范的写法。

其他复现方式

只要是在同一个表达式中创建两个无引用的临时对象,都可能出现ID相同的情况,比如:

# 两次创建空列表
print(id([]), id([]))
# 两次调用list()生成副本
print(id(list([1,2,3])), id(list([1,2,3])))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:27:36