题
长话短说,我有一个重要的 Python 应用程序,除其他外,它还可以调用“losetup”、“mount”等。在 Linux 上。主要消耗系统资源,完成后必须释放这些资源。
如果我的应用程序崩溃,我想确保这些系统资源得到正确释放。
做下面这样的事情有意义吗?
def main():
# TODO: main application entry point
pass
def cleanup():
# TODO: release system resources here
pass
if __name__ == "__main__":
try:
main()
except:
cleanup()
raise
这是通常做的事情吗?有没有更好的办法?也许是单例类中的析构函数?
解决方案
一般来说,我喜欢顶级异常处理程序(无论语言如何)。它们是清理可能与引发异常的方法内消耗的资源不直接相关的资源的好地方。
这也是一个很棒的地方 日志 如果您有这样的框架,则可以排除这些例外情况。顶级处理程序会捕获那些您没有计划的奇怪异常,并让您在将来纠正它们,否则,您可能根本不知道它们。
请注意您的顶级处理程序不会抛出异常!
其他提示
析构函数(如在 __del__ 方法中)是一个坏主意,因为不能保证调用它们。atexit 模块是一种更安全的方法,尽管如果 Python 解释器崩溃(而不是 Python 应用程序),或者使用 os._exit() ,或者进程被积极终止,或者机器重新启动,这些模块仍然不会触发。(当然,最后一项在您的情况下不是问题。)如果您的进程容易崩溃(例如,它使用变化无常的第三方扩展模块),您可能需要在简单的父进程中进行清理更多的隔离。
如果您真的不担心,请使用 atexit 模块。
应用程序范围的处理程序很好。它们非常适合伐木。只需确保应用程序范围内的应用程序是耐用的并且不太可能自行崩溃。
当然,如果您使用类,则应该释放它们在析构函数中分配的资源。使用尝试:如果您想释放类的析构函数尚未释放的资源,则在整个应用程序上。
您应该使用以下块,而不是使用包罗万象的 except::
try:
main()
finally:
cleanup()
这将确保以更Pythonic的方式进行清理。
这似乎是一种合理的方法,并且比单例类上的析构函数更直接、更可靠。您还可以查看“退出“ 模块。(发音为“at exit”,而不是“a tex it”或类似的东西。我困惑了很长一段时间。)
考虑编写一个上下文管理器并使用 with 语句。