确定python是否正在退出

时间:2014-03-21 20:29:41

标签: python destructor

有没有办法确定python是否正在关闭?

基本上:

def Foo(object):
  def __del__(self):
    if PYTHON_IS_EXITING:
      do_this
    else:
      do_that

foo1 = Foo()
del foo1 # calls do_that
foo2 # calls do_this when python exits

上下文是多处理的。当python退出时,ThreadPool不起作用,并且do_that将并行执行,而do_this将串行执行。

由于

2 个答案:

答案 0 :(得分:2)

您可以尝试使用atexit

import atexit

def stufftodowhenpythonquits():
    # do some stuff

atexit.register(stufftodowhenpythonquits)

答案 1 :(得分:0)

以亚当·史密斯的话为基础...

如果您安排atexit拆除您的物体,则很有可能您不需要 做任何不同的事情。因为当atexit运行其注册功能时,您想要使用的ThreadPool尚未被拆除。因此,如果在退出之前被调用,则atexit注册的函数可以(可能)完全执行析构函数的操作。

但是等等,还有更多。

考虑以下稍微不适的建议尝试,以处理退出前与退出前的物体撕裂:

#!/usr/bin/python3

import atexit

class Foo:
    def __init__(self):
        self.dead = False
        atexit.register(self.atexit)

    def __del__(self):
        print("%s: in destructor, self.dead is %s"%(id(self), self.dead))
        if not self.dead: self.atexit()

    def atexit(self):
        print("%s: in atexit"%id(self))
        self.dead = True
        atexit.unregister(self.atexit)
        # Do whatever end-of-life processing you need here.  Whether
        # we got here from our destructor or the atexit modules
        # processing, whatever resources we need should (probably)
        # still be available.

foo1 = Foo()
foo2 = Foo()

print("foo1: %s, foo2: %s"%(id(foo1), id(foo2)))
del foo1

如果运行此命令,则会看到两个 对象在调用析构函数时已经调用了其atexit()方法。这是因为,由于对象的atexit()方法已向atexit模块注册,因此atexit模块将保留对该对象的引用。因此,即使在del删除之后,该对象仍会停留直到退出。

如果您不需要快速垃圾回收,那可能没关系。 (在这种情况下,您可以摆脱self.dead标志和析构函数。因为析构函数将永远不会在atexit调用的对象被拆除之前被调用,因此调用析构函数时将永远无所事事)

如果您要做,则需要在退出之前将对象移开-好吧,剩下的工作留给读者练习。 :-)