python 如何让python优雅地失败?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/497952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make python gracefully fail?
提问by FurtiveFelon
I was just wondering how do you make python fail in a user defined way in all possible errors.
我只是想知道如何在所有可能的错误中以用户定义的方式使 python 失败。
For example, I'm writing a program that processes a (large) list of items, and some of the items may not be in the format I defined. If python detects an error, it currently just spits out an ugly error message and stop the whole process. However, I want it to just outputs the error to somewhere together with some context and then move on to the next item.
例如,我正在编写一个程序来处理一个(大)项目列表,其中一些项目可能不是我定义的格式。如果 python 检测到错误,它目前只是吐出一个丑陋的错误消息并停止整个过程。但是,我希望它只是将错误与一些上下文一起输出到某个地方,然后继续下一个项目。
If anyone can help me with this it would be greatly appreciated!
如果有人能帮助我解决这个问题,将不胜感激!
Thanks a lot!
非常感谢!
Jason
杰森
回答by piro
The following are a few basic strategies I regularly use in my more-than-trivial scripts and medium-size applications.
以下是我经常在我的超简单脚本和中型应用程序中使用的一些基本策略。
Tip 1: Trap the error at every level where it makes sense to continue processing. In your case it may be in the inside the loop. You don't have to protect every single line or every single function call, but only the places where it makes a difference to survive the error.
提示 1:在可以继续处理的每个级别捕获错误。在您的情况下,它可能在循环内部。您不必保护每一行或每一个函数调用,而只需保护那些对避免错误产生影响的地方。
Tip 2: Use the logging module to report what happened in a way that is configurable independently from how you compose the module with other modules in a larger applications. Start importing the root logger in your module, then, using it in a few different places, you may eventually figure out a more sensible logging hierarchy.
技巧 2:使用日志记录模块以一种可配置的方式报告发生的事情,这种方式独立于您在更大的应用程序中将模块与其他模块组合的方式。开始在您的模块中导入根记录器,然后在几个不同的地方使用它,您最终可能会找出更合理的日志记录层次结构。
import logging
logger = logging.getLogger()
for item in items:
try:
process(item)
except Exception, exc:
logger.warn("error while processing item: %s", exc)
Tip 3: define an "application exception", eventually you may want to define a hierarchy of such exception but this is better discovered when the need arise. Use such exception(s) to "bubble out" when the data you are dealing with are not what you expected or to signal inconsistent situations, while separating them from the normal standard exception arising from regular bugs or problems outside the modeled domain (IO errors etc).
技巧 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
The main function is the outmost checkpoint: finally deal here with the possible ways your task finished. If this was not a shell script (but e.g. the processing beneath a dialog in an UI application or an operation after a POST in a web application) only the way you report the error changes (and the use of the logging method completely separates the implementation of the processing from its interface).
主要功能是最外层的检查点:最后在这里处理您的任务完成的可能方式。如果这不是 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())
回答by dF.
The ugly error message means that an exception is raised. You need to catch the exception.
丑陋的错误消息意味着引发了异常。您需要捕获异常。
A good place to start is the Python tutorial's section on exceptions.
一个很好的起点是Python 教程中关于异常的部分。
Basically you need to wrap your code in a try...except
block like this:
基本上,您需要将代码包装在这样的try...except
块中:
try:
do_something_dangerous()
except SomeException:
handle_the_error()
回答by SilentGhost
use try... exceptidiom
使用try... 除了成语
try:
# code that possibly breaks
except RelevantError: # you need to know what kind of errors you code might produce
# show your message
回答by sykora
all possible errors
所有可能的错误
The other answers pretty much cover how to make your program gracefully fail, but I'd like to mention one thing -- You don't want to gracefully fail allerrors. If you hide all your errors, you won't be shown those which signify that the logic of the program is wrong - namely errors you wantto see.
其他答案几乎涵盖了如何让您的程序优雅地失败,但我想提一件事——您不想优雅地失败所有错误。如果您隐藏所有错误,您将不会看到那些表明程序逻辑错误的错误——即您想看到的错误。
So while it's important to catch your exceptions, make sure you know exactly which exceptions are actually being caught.
因此,虽然捕获异常很重要,但请确保您确切地知道实际捕获了哪些异常。
回答by John Mulder
When Python runs into an error condition, it is throwing a exception.
当 Python 遇到错误情况时,它会抛出异常。
The way to handle this is to catch the exception and maybe handle it.
处理这个问题的方法是捕获异常并可能处理它。
You might check out the section on exceptions on the python tutorial.
您可以查看 python教程中有关异常的部分。
You expressed an interest in catching all exceptions. This could be done by catching the Exception class. according to the documentation:
您表示有兴趣捕获所有异常。这可以通过捕获 Exception 类来完成。根据文档:
All built-in, non-system-exiting exceptions are derived from this class. All user-defined exceptions should also be derived from this class
所有内置的、非系统退出的异常都是从这个类派生的。所有用户定义的异常也应该从这个类派生