以亚当·斯密所说的为基础......
如果您安排 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 调用的对象销毁之前永远不会调用析构函数,所以调用析构函数时总是无事可做.)
如果您确实需要在退出之前让对象离开——好吧,解决这个问题留给读者作为练习。 :-)