如何让python优雅地失败?

时间:2009-01-31 01:22:08

标签: python

我只是想知道如何在所有可能的错误中以用户定义的方式使python失败。

例如,我正在编写一个处理(大)项目列表的程序,而某些项目可能不是我定义的格式。如果python检测到错误,它当前只会发出一个丑陋的错误消息并停止整个过程。但是,我希望它只是将错误输出到某个地方以及某些上下文,然后转到下一个项目。

如果有人能帮助我,我们将不胜感激!

非常感谢!

杰森

5 个答案:

答案 0 :(得分:25)

以下是我经常在我的琐碎脚本和中型应用程序中使用的一些基本策略。

提示1:在有意义继续处理的每个级别捕获错误。在你的情况下,它可能在循环内部。您不必保护每一行或每一个函数调用,而只需保护它能够在错误中生效的地方。

技巧2:使用日志记录模块以可配置的方式报告发生的事件,与在较大的应用程序中将模块与其他模块组合的方式无关。开始在模块中导入根记录器,然后在几个不同的地方使用它,最终可能会找到一个更合理的记录层次结构。

import logging
logger = logging.getLogger()

for item in items:
    try:
        process(item)
    except Exception, exc:
        logger.warn("error while processing item: %s", exc)

技巧3:定义“应用程序异常”,最终您可能希望定义此类异常的层次结构,但在需要时可以更好地发现。当您处理的数据不符合您的预期或发出不一致的情况时,使用此类异常来“冒泡”,同时将它们与模拟域外的常规错误或问题引起的正常标准异常分开(IO错误)等)。

class DomainException(Exception):
    """Life is not what I expected"""

def process(item):
    # There is no way that this item can be processed, so bail out quickly.
    # Here you are assuming that your caller will report this error but probably
    # it will be able to process the other items.
    if item.foo > item.bar:
        raise DomainException("bad news")

    # Everybody knows that every item has more that 10 wickets, so
    # the following instruction is assumed always being successful.
    # But even if luck is not on our side, our caller will be able to
    # cope with this situation and keep on working
    item.wickets[10] *= 2

主要功能是最外面的检查点:最后处理你的任务完成的可能方式。如果这不是shell脚本(但是例如UI应用程序中的对话框下的处理或Web应用程序中的POST之后的操作),则仅报告错误的方式发生更改(并且使用日志记录方法完全分离实现从其界面处理)。

def main():
    try:
        do_all_the_processing()
        return 0
    except DomainException, exc:
        logger.error("I couldn't finish. The reason is: %s", exc)
        return 1
    except Exception, exc:
        logger.error("Unexpected error: %s - %s", exc.__class__.__name__, exc)
        # In this case you may want to forward a stacktrace to the developers via e-mail
        return 1
    except BaseException:
        logger.info("user stop") # this deals with a ctrl-c
        return 1

if __name__ == '__main__':
    sys.exit(main())

答案 1 :(得分:8)

丑陋的错误消息表示引发了异常。你需要捕捉异常。

一个好的起点是Python tutorial's section on exceptions.

基本上,您需要将代码包装在try...except块中,如下所示:

try:
    do_something_dangerous()
except SomeException:
    handle_the_error()

答案 2 :(得分:3)

使用try... except成语

try:
    # code that possibly breaks
except RelevantError:          # you need to know what kind of errors you code might produce
    # show your message

答案 3 :(得分:2)

  

所有可能的错误

其他答案几乎涵盖了如何让你的程序优雅地失败,但我想提一件事 - 你不想优雅地失败所有错误。如果您隐藏所有错误,则不会显示那些表示程序逻辑错误的错误 - 即您希望看到的错误。

因此,尽管捕获异常非常重要,但请确保确切知道实际捕获的异常。

答案 4 :(得分:0)

当Python遇到错误情况时,它会抛出异常。

处理此问题的方法是捕获异常并处理它。

您可以查看python tutorial上的例外部分。

您表示有兴趣抓住所有例外情况。这可以通过捕获Exception类来完成。根据文件:

  

所有内置,非系统退出   异常来源于此   类。所有用户定义的异常   也应该从这个类派生出来