Python 捕获所有异常的缺点(在最高程序级别,然后重新提升,只是在退出之前记录?)

Python 捕获所有异常的缺点(在最高程序级别,然后重新提升,只是在退出之前记录?),python,exception,Python,Exception,我在远程机器上有一个长时间运行的程序,我希望确保(1)我有导致它终止的任何异常的记录,(2)如果它终止,会通知某人。有人看到我使用的方法的缺点吗?(或者有更好的建议?) 我在这里阅读了Python文档和许多与异常相关的帖子,并理解“除外覆盖”子句通常是个坏主意。在子程序和模块中,我始终 使用except来处理特定的预期异常,但在程序的最高级别使用“catch all”except子句似乎很有用,以确保我可以在程序退出之前记录异常 你觉得怎么样 import traceback try:

我在远程机器上有一个长时间运行的程序,我希望确保(1)我有导致它终止的任何异常的记录,(2)如果它终止,会通知某人。有人看到我使用的方法的缺点吗?(或者有更好的建议?)


我在这里阅读了Python文档和许多与异常相关的帖子,并理解“除外覆盖”子句通常是个坏主意。在子程序和模块中,我始终 使用except来处理特定的预期异常,但在程序的最高级别使用“catch all”except子句似乎很有用,以确保我可以在程序退出之前记录异常

你觉得怎么样

import traceback
try:
    # main program code here
except BaseException:
    tb = traceback.format_exc()
    msg = "Exiting program due to exception:" + tb
    LogToFile(msg)         # custom logging function
    SendAlertEmail(msg)    # warn admin that program terminated
    raise                  # program exits with the existing exception
请注意,我使用的是BaseException而不是Exception,因为如果终端上有人按下Ctrl-C,我希望将其记录为退出程序的原因(并提醒管理员程序已退出)。但我想我也可以用:

except Exception, KeyboardInterrupt:

没有具体的缺点,但有一个很好的选择--

在您的特定版本中,考虑使用“裸代码”>:,和<代码> sys .ExcIfIOFER()/代码>以获得异常信息;这将确保您捕获所有内容——即使是在某些模块引发的异常情况下,而不是

BaseException
子类的实例。例如:

>>> class X: pass
... 
>>> raise X
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.X: <__main__.X instance at 0xc9ad0>
>>X级:通过
... 
>>>升起X
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
__main_uux.X:
正如您所看到的,仍然可以提出一个
除了BaseException:
不会捕获的东西,这就是为什么bare exception
除了:
仍然存在的原因(特别是对于像您这样的非常特殊的用途!)


无论您使用钩子还是建立自己的,考虑(可能取决于配置标志或环境设置)不向终端用户负担所有的细节(仅仅是一个改进的用户体验的巧妙接触),只是一个有意义的总结(让用户放心,所有问题的细节已经被记录等)。.

考虑如果异常是由于磁盘空间不足引起的,会发生什么情况。如果日志记录写入同一分区

LogToFile(msg)
将引发异常,因此也不会发送电子邮件。对每种方法进行简单的尝试/排除可以避免该问题

tb = traceback.format_exc()
msg = "Exiting program due to exception:" + tb
try:
    LogToFile(msg)         # custom logging function
except:
    pass
try:
    SendAlertEmail(msg)    # warn admin that program terminated
except:
    pass
raise                  # program exits with the existing exception
“我在这里阅读了Python文档和许多与异常相关的帖子,并理解“除外”子句通常是个坏主意。”


这样做的理由是,你可能预期会出现三种例外情况,但最终会吞下你从未考虑过的第四种例外情况。执行无条件重新引发的处理程序消除了这一问题——您将看到意外的异常——因此这是一个与一般规则完全不同的异常。

感谢您的快速响应和有用的注释,并指出并非所有模块异常都必须继承自BaseException。(顺便说一句,我是一个全新的用户,所以我似乎还不能给你的答案投票)@emdash,是的,你需要我认为15个代表来投票(但你总是可以接受对你最有帮助的答案——当然,过一段时间看看是否有人来了——然后开始做销售代表,因为你也会得到一些销售代表,尽管被接受的回答会得到更多)。谢谢,说得好。如果我想记录每一个异常,我可以另外发送电子邮件/保存在保存/发送第一个异常的过程中发生的任何异常。@fmark,我最近收到了一大堆driveby的否决票。可能是同一个人的。也许他们不喜欢裸体的
,除了:
。不知道惯性导航与制导。。。