Python中仅删除一个对象却触发两个对象析构的原因
Python中仅删除一个对象却触发两个对象析构的原因
嗨,这个问题其实和Python的对象生命周期管理,以及程序退出时的自动清理机制有关,我来给你拆解清楚:
首先梳理下你程序的实际执行流程
你写的代码执行步骤是这样的:
- 创建对象
a,ball_count变为1,打印创建信息; - 创建对象
b,ball_count变为2,打印创建信息; - 执行
del a:此时a的引用计数降为0,触发它的__del__方法,ball_count变回1,你看到了a的析构日志; - 打印剩余球的数量;
- 程序执行到末尾,开始自动退出。
关键原因:Python程序退出时会自动清理所有剩余对象
你看到的b的析构日志,并不是因为你del a导致的,而是当Python脚本执行完毕时,它会自动回收当前进程中所有还存在的对象——也就是你的b对象。这时候b的__del__方法会被调用,所以你会误以为是del a触发了它的析构。
同样的,当你换成del b时:
del b触发b的析构,ball_count变为1;- 程序继续执行到末尾,
a对象还存在,所以程序退出时会自动清理a,触发a的__del__方法; - 最终你还是会看到两个对象的析构日志。
验证这个结论的小实验
你可以给程序加一段暂停代码,就能清晰看到区别:
import time class TennisBall: ball_count = 0 def __init__(self, serial_number, age): self.serial_number = serial_number self.age = age print("New Tennis Ball created {}!".format(self.serial_number)) TennisBall.ball_count +=1 def __del__(self): print("Tennis ball {} has been deleted :(".format(self.serial_number)) TennisBall.ball_count -= 1 a = TennisBall(1234, 0) print("Num balls: {} ".format(TennisBall.ball_count)) b = TennisBall(2345, 0) print("Num balls: {} ".format(TennisBall.ball_count)) del a print("Num balls after del ball a: {} ".format(TennisBall.ball_count)) # 新增暂停代码,观察析构时机 time.sleep(5) print("程序即将退出")
运行这段代码你会发现:
- 执行
del a后,只有a的析构日志打印出来; - 接下来的5秒sleep期间,完全没有
b的析构日志; - 只有当sleep结束,
print("程序即将退出")执行完,程序彻底退出时,b的析构日志才会出现。
这样就能明确:第二个对象的析构是程序退出的自动清理行为,和你主动del第一个对象没有直接关系。
备注:内容来源于stack exchange,提问作者user4805834
相关产品推荐
相关产品推荐

