我有一个包含类的python脚本.
这个类有一个__del__
常规清理方法.如果我在正常执行脚本期间删除了类,我想要完成一些清理工作.
我也有一个信号处理程序,它做了一些不寻常的清理工作.如果脚本在收到信号时正在执行其他操作,则需要进行一些额外的清理,然后进行常规清理.
我注意到做del self
和之间有区别self.__del__()
.
即,self.__del__()
调用该del
方法两次.
你能解释一下为什么会这样吗?
这是一个模拟脚本来说明问题:
import sys import signal from optparse import OptionParser class TestClass(object): def __init__(self, del_self): self.del_self = del_self print "__init__ with del_self = %s" % self.del_self def __del__(self): print "Now performing usual cleanup." def signal_handler(self, arg_1, arg_2): print "Received signal. Now performing unusual cleanup." # Unusual cleanup print "Did unusual cleanup" if self.del_self: print("Doing del self") del self else: print("Doing self.__del__()") self.__del__() sys.exit(0) if __name__ == '__main__': arguments = sys.argv[1:] parse = OptionParser("Test.") parse.add_option( "-d", "--delself", help="Set del self.", type="int", default=1 ) (options, _) = parse.parse_args() print "Options: %s" % options tc = TestClass(del_self=options.delself) signal.signal(signal.SIGQUIT, tc.signal_handler) while True: pass
如果我运行脚本:
python deltest.py --delself 1
问题killall -3 python
我得到:
Received signal. Now performing unusual cleanup. Did unusual cleanup Doing del self Now performing usual cleanup.
如果,如果我python deltest.py --delself 0
再次执行kill信号,我得到:
Received signal. Now performing unusual cleanup. Did unusual cleanup Doing self.__del__() Now performing usual cleanup. Now performing usual cleanup.
为什么__del__
在这种情况下方法执行两次?
谢谢!
del self
什么都没做 - 它只删除命名的局部变量self
.但由于这不是对实例的最后一次引用(无论什么叫做此方法,至少还有一个引用),该对象将继续存在.
__del__
除了运行该方法外,手动调用也没有任何作用; 它不会删除任何东西.
什么做的工作是去掉最后一个引用的对象:在这种情况下,del tc
里面的主要方法必须删除最后一个引用,就我所看到的.然后该对象将被垃圾收集,然后Python调用__del__
.
这就是为什么__del__
会发生两次:一次是手动调用它作为普通函数,一次是在程序结束时对象被垃圾收集.