长话短说,我有一个实质性的Python应用程序,其中包括在Linux上向“losetup”,“mount”等发出呼叫。基本消耗必须在完成时释放的系统资源。
如果我的应用程序崩溃,我想确保正确释放这些系统资源。
执行以下操作是否有意义?
def main():
# TODO: main application entry point
pass
def cleanup():
# TODO: release system resources here
pass
if __name__ == "__main__":
try:
main()
except:
cleanup()
raise
这通常是做什么的吗?有没有更好的办法?也许是单例类中的析构函数?
答案 0 :(得分:11)
我喜欢一般的顶级异常处理程序(无论语言如何)。它们是清理资源的好地方,这些资源可能与引发异常的方法中消耗的资源无法立即相关。
如果您有这样的框架,那么记录这些异常也是一个很棒的地方。顶级处理程序将捕获您未计划的那些奇怪的异常,并允许您在将来更正它们,否则,您可能永远不会知道它们。
请注意,您的顶级处理程序不会抛出异常!
答案 1 :(得分:7)
析构函数(在__del__方法中)是一个坏主意,因为不能保证调用它们。 atexit模块是一种更安全的方法,虽然如果Python解释器崩溃(而不是Python应用程序),或者如果使用os._exit(),或者进程被激活,或者机器重新启动,它们仍然不会触发。 (当然,在您的情况下,最后一项不是问题。)如果您的进程容易崩溃(例如,它使用变幻无常的第三方扩展模块),您可能希望在简单的父进程中进行清理更加孤立。
如果您并不担心,请使用atexit模块。
答案 2 :(得分:2)
应用程序范围处理程序很好。它们非常适合伐木。只要确保应用程序范围宽,并且不太可能自行崩溃。
答案 3 :(得分:2)
如果你使用类,你应该释放他们在析构函数中分配的资源,当然。如果您想释放类的析构函数尚未释放的资源,请在整个应用程序上使用try:。
除了使用catch-all而不是:,你应该使用以下块:
try:
main()
finally:
cleanup()
这将确保以更加pythonic的方式进行清理。
答案 4 :(得分:1)
这似乎是一种合理的方法,比单例类的析构函数更直接,更可靠。您还可以查看“atexit”模块。 (发音为“at exit”,而不是“tex it”或类似的东西。我混淆了很久。)
答案 5 :(得分:1)
考虑编写上下文管理器并使用with语句。