del self vs self.\uuu del\uu()和python中正确的清理方法是什么?

2024-10-05 13:15:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含类的python脚本。

这个类有一个用于通常清理的__del__方法。如果我在脚本的正常执行过程中删除类,我希望进行一些清理。

我还有一个信号处理器,它可以做一些不寻常的清理。如果脚本在接收到信号时正在执行其他操作,则需要执行一些额外的清理,然后执行常规清理。

我注意到做del selfself.__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__方法要执行两次?

谢谢!


Tags: 方法importself脚本signalparsenowcleanup
1条回答
网友
1楼 · 发布于 2024-10-05 13:15:19

del self几乎什么也不做——它只删除名为self局部变量。但由于这不是对实例的最后一次引用(不管调用了什么方法,至少还有一个引用),对象将继续存在。

手动调用__del__除了运行该方法之外,什么都不会实现;它不会删除任何内容。

所做的工作是删除对一个对象的最后一个引用:在本例中,del tc在main方法中可能已经删除了最后一个引用,就我所见。然后对象将被垃圾收集,然后Python调用__del__

这就是为什么__del__会发生两次:一次是作为普通函数手动调用它,另一次是在程序结束时垃圾回收对象。

相关问题 更多 >

    热门问题