Python引用计数机制下清空prev列表后now列表引用未失效原因咨询
现象原理说明
你遇到的行为是Python引用计数和容器存储逻辑的正常表现,你的示例代码如下:
class dummy: pass prev = [dummy() for _ in range(5)] now = [] for d in prev: now.append(d) for idx in range(5): print(prev[idx] is now[idx]) # 输出全为True,说明复制的是同一个引用 prev.clear() print(prev) # 输出空列表 print(now) # 5个dummy对象仍然存在
执行流程的底层逻辑可以拆解为3步:
- 运行
prev = [dummy() for _ in range(5)]时,Python创建了5个dummy类实例,每个实例的引用计数为1(被prev列表中的元素指向) - 循环把元素
append到now列表时,是将prev中存储的引用地址复制了一份存入now,此时每个dummy实例的引用计数变为2 - 运行
prev.clear()时,仅清空了prev列表自身存储的所有引用地址,每个dummy实例的引用计数减1变为1,仍然被now列表中的引用指向,所以不会被垃圾回收器销毁,now里的引用自然有效。
和相关问题的原理一致性
你找到的相关问题和你遇到的现象原理完全相同:删除任意一个持有对象引用的容器/变量,只会减少对应对象的引用计数,只要对象还有其他存活的引用,就不会被回收,其他引用也不会失效。
Python引用和C++引用的核心差异
二者是完全不同的概念,这也是你产生困惑的核心原因:
- C++的引用是变量的别名,和原变量对应同一块内存,没有独立的生命周期,也不参与对象的内存管理,不存在「复制引用、引用计数」的逻辑
- Python的引用本质是携带引用计数的对象指针,每个引用都是独立的实体,可以被复制、销毁,对象的生命周期由引用计数决定,只有所有指向该对象的引用都被销毁时,对象才会被回收。
内容的提问来源于stack exchange,提问作者goldenriver4422
相关产品推荐
相关产品推荐

