del self vs self.__del__() - 在 python 中清理的正确方法是什么?
del self vs self.__del__() - and what is the proper way to cleanup in python?
我有一个包含 class 的 python 脚本。
此 class 有一个 __del__
方法用于常规清理。如果我在脚本的正常执行期间删除了 class,我希望进行一些清理工作。
我还有一个信号处理程序,可以进行一些不寻常的清理。如果脚本在收到信号时正在执行其他操作,则需要进行一些额外的清理,然后再进行常规清理。
我注意到 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
然后是终止信号,我会得到:
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__
除了 运行 该方法外,也没有任何效果;它不会删除任何内容。
所做的工作是删除对对象的最后引用:在这种情况下,main 方法中的 del tc
会删除最后一个引用,只要我可以看到。然后该对象将被垃圾收集,然后 Python 调用 __del__
.
所以这就是 __del__
发生两次的原因:一次是当您将其作为普通函数手动调用时,另一次是在程序结束时对对象进行垃圾回收。
我有一个包含 class 的 python 脚本。
此 class 有一个 __del__
方法用于常规清理。如果我在脚本的正常执行期间删除了 class,我希望进行一些清理工作。
我还有一个信号处理程序,可以进行一些不寻常的清理。如果脚本在收到信号时正在执行其他操作,则需要进行一些额外的清理,然后再进行常规清理。
我注意到 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
然后是终止信号,我会得到:
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__
除了 运行 该方法外,也没有任何效果;它不会删除任何内容。
所做的工作是删除对对象的最后引用:在这种情况下,main 方法中的 del tc
会删除最后一个引用,只要我可以看到。然后该对象将被垃圾收集,然后 Python 调用 __del__
.
所以这就是 __del__
发生两次的原因:一次是当您将其作为普通函数手动调用时,另一次是在程序结束时对对象进行垃圾回收。