应用程序范围的异常处理程序有意义吗?

时间:2020-03-06 14:22:55  来源:igfitidea点击:

长话短说,我有一个强大的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

这是通常要做的事情吗?有没有更好的办法?也许是单例课程中的析构函数?

解决方案

应用程序范围的处理程序很好。它们非常适合记录日志。只要确保应用程序范围内的应用程序是持久的并且不会崩溃即可。

我总体上喜欢顶级异常处理程序(无论使用哪种语言)。它们是清理可能与引发异常的方法中消耗的资源不立即相关的资源的好地方。

如果我们有这样的框架,它也是记录这些异常的理想之地。顶级处理程序将捕获那些我们没有计划的奇异异常,并让我们将来对其进行纠正,否则,我们可能根本一无所知。

请注意,顶级处理程序不要抛出异常!

析构函数(如__del__方法中的方法)是个坏主意,因为不能保证调用它们。 atexit模块是一种更安全的方法,尽管如果Python解释器崩溃(而不是Python应用程序),使用os._exit()或者进程被致命地杀死或者计算机重新启动,这些方法仍然不会触发。 (当然,对于我们而言,最后一项不是问题。)如果进程容易崩溃(例如,它使用多变的第三方扩展模块),则可能需要在一个简单的父进程中进行清理更多隔离。

如果我们不太担心,请使用atexit模块。

这似乎是一种合理的方法,并且比单例类的析构函数更直接,更可靠。我们可能还会查看" atexit"模块。 (发音是"退出",而不是" tex"之类的东西。我很长一段时间都感到困惑。)

当然,如果使用类,则应该释放它们在析构函数中分配的资源。即使我们想释放类的析构函数尚未释放的资源,也可以在整个应用程序上使用try:。

而不是使用包罗万象的除外:,我们应该使用以下代码块:

try:
    main()
finally:
    cleanup()

这将确保以更pythonic的方式进行清理。

考虑编写上下文管理器并使用with语句。