Python中对象退出作用域后是否自动销毁?存入全局列表的对象能否正常访问?
问题解答
结论先行
你两个问题的答案分别是:
- 退出for循环后,你在循环内创建的所有
Tree实例的析构函数不会被自动调用 - 你完全可以在循环外部通过全局变量
trees访问到所有对应的Tree实例
原理说明
Python的对象生命周期管理逻辑和C++有本质区别:
- C++中在代码块内声明的栈变量,退出代码块时就会自动触发析构,要是你只把栈对象的指针存到外部容器,退出作用域后指针就会变成野指针。但Python没有栈分配的对象,所有类实例都是在堆上分配内存,你声明的变量只是指向实例的引用。
- 针对你给出的代码片段,每次循环的执行逻辑如下:
- 执行
tree = Tree():在堆上创建一个Tree实例,将实例的引用赋值给临时变量tree,此时实例的引用计数为1 - 执行
trees.append(tree):将实例的引用复制一份存入全局列表trees,此时实例的引用计数增加为2 - 单次循环结束,临时变量
tree被销毁,实例的引用计数减1,剩余1的引用计数来自全局列表trees
- 执行
- 只有当对象的引用计数归零的时候,Python的垃圾回收机制才会销毁该对象,并调用其
__del__析构方法。由于你的trees是全局变量,只要trees本身没有被销毁、或者你没有手动删除trees里的对应元素,所有Tree实例的引用计数就永远不会归零,自然不会被析构,你随时可以通过trees的索引访问到对应的实例。
内容的提问来源于stack exchange,提问作者solar_power
相关产品推荐
相关产品推荐

