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

Posted

技术标签:

【中文标题】应用程序范围的异常处理程序有意义吗?【英文标题】:Does an application-wide exception handler make sense? 【发布时间】:2010-09-10 20:56:22 【问题描述】:

长话短说,我有一个实质性的 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

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

【问题讨论】:

【参考方案1】:

我喜欢一般的***异常处理程序(不管是什么语言)。它们是清理资源的好地方,这些资源可能与引发异常的方法中消耗的资源没有直接关系。

如果您有这样的框架,这也是一个记录这些异常的好地方。***处理程序将捕获那些您没有计划的奇怪异常,并让您在将来更正它们,否则您可能根本不知道它们。

请注意您的***处理程序不会引发异常!

【讨论】:

***异常处理程序在 GUI 应用程序中很有用。事件处理程序中抛出的未捕获异常将显示在控制台中,但通常不会使程序崩溃(例如在 PyGTK 和 PyQt 中),这可能会被忽视。如果您在处理程序中显示错误对话框,则没有该问题。 我还建议您将它们放在执行批处理的控制台应用程序中。我让他们发送一封电子邮件,以便我们可以收到任何问题的通知,但至少它可以记录下来。【参考方案2】:

析构函数(如在 __del__ 方法中)是个坏主意,因为不能保证调用它们。 atexit 模块是一种更安全的方法,尽管如果 Python 解释器(而不是 Python 应用程序)崩溃,或者使用 os._exit(),或者进程被积极终止,或者机器重新启动,这些模块仍然不会触发。 (当然,最后一项在您的情况下不是问题。)如果您的进程容易崩溃(例如,它使用变化无常的第三方扩展模块),您可能希望在一个简单的父进程中进行清理更多的隔离。

如果您不担心,请使用 atexit 模块。

【讨论】:

我也不完全确定会调用析构函数。感谢您的澄清!看来 atexit 是我需要的。【参考方案3】:

应用程序范围的处理程序很好。它们非常适合记录。只需确保应用程序范围内的应用程序是持久的并且不太可能自行崩溃。

【讨论】:

【参考方案4】:

如果你使用类,你当然应该释放它们在析构函数中分配的资源。在整个应用程序上使用 try: 只是为了释放尚未被类的析构函数释放的资源。

您应该使用以下块,而不是使用包罗万象的 except::

try:
    main()
finally:
    cleanup()

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

【讨论】:

【参考方案5】:

这似乎是一种合理的方法,并且比单例类的析构函数更直接和可靠。您还可以查看“atexit”模块。 (发音为“at exit”,而不是“a tex it”之类的。我混淆了很长时间。)

【讨论】:

【参考方案6】:

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

【讨论】:

以上是关于应用程序范围的异常处理程序有意义吗?的主要内容,如果未能解决你的问题,请参考以下文章

Ruby异常处理的基础

引发异常的范围,在 PLSQL 代码中处理自己的异常

python 异常处理

python的异常处理

Python基础:异常处理

C# 程序异常管理方案