Python 在这种情况下如何防止“过于广泛的例外”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30442236/
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 prevent "too broad exception" in this case?
提问by Blusky
I got a list of functions that may fail, and if one fail, I don't want the script to stop, but to continue with next function.
我得到了一个可能失败的函数列表,如果一个函数失败,我不希望脚本停止,而是继续执行下一个函数。
I am executing it with something like this :
我正在用这样的东西执行它:
list_of_functions = [f_a,f_b,f_c]
for current_function in list_of_functions:
try:
current_function()
except Exception:
print(traceback.format_exc())
It's working fine, but it is not PEP8 compliant:
它工作正常,但不符合 PEP8:
When catching exceptions, mention specific exceptions whenever possible instead of using a bare except: clause.
For example, use:
try: import platform_specific_module except ImportError: platform_specific_module = None
A bare except: clause will catch SystemExit and KeyboardInterrupt exceptions, making it harder to interrupt a program with Control-C, and can disguise other problems. If you want to catch all exceptions that signal program errors, use except Exception: (bare except is equivalent to except BaseException: ).
A good rule of thumb is to limit use of bare 'except' clauses to two cases:
If the exception handler will be printing out or logging the traceback; at least the user will be aware that an error has occurred.
If the code needs to do some cleanup work, but then lets the exception propagate upwards with raise . try...finally can be a better way to handle this case.
捕获异常时,尽可能提及特定的异常,而不是使用一个空的 except: 子句。
例如,使用:
try: import platform_specific_module except ImportError: platform_specific_module = None
一个空的 except: 子句将捕获 SystemExit 和 KeyboardInterrupt 异常,使得用 Control-C 中断程序变得更加困难,并且可以掩盖其他问题。如果您想捕获所有发出程序错误信号的异常,请使用 except Exception:(bare except 等价于 except BaseException: )。
一个好的经验法则是将裸“except”子句的使用限制为两种情况:
如果异常处理程序将打印或记录回溯;至少用户会意识到发生了错误。
如果代码需要做一些清理工作,然后让异常向上传播 raise 。try...finally 可以成为处理这种情况的更好方法。
How to this the good way ?
这个好方法如何?
采纳答案by Ed Smith
The PEP8 guide you quote suggests that it is okay to use a bare exception in your case provided you are logging the errors. I would think that you should cover as many exceptions as you can/know how to deal with and then log the rest and pass
, e.g.
您引用的 PEP8 指南表明,只要您正在记录错误,就可以在您的情况下使用裸异常。我认为您应该尽可能多地涵盖/知道如何处理的异常,然后记录其余的pass
,例如
import logging
list_of_functions = [f_a,f_b,f_c]
for current_function in list_of_functions:
try:
current_function()
except KnownException:
raise
except Exception as e:
logging.exception(e)
回答by Dunes
Do you perhaps mean that each function can raise different exceptions? When you name the exception type in the except clause it can be any name that refers to an exception, not just the class name.
您可能是说每个函数都可以引发不同的异常?当您在 except 子句中命名异常类型时,它可以是引用异常的任何名称,而不仅仅是类名。
eg.
例如。
def raise_value_error():
raise ValueError
def raise_type_error():
raise TypeError
def raise_index_error():
doesnt_exist
func_and_exceptions = [(raise_value_error, ValueError), (raise_type_error, TypeError),
(raise_index_error, IndexError)]
for function, possible_exception in func_and_exceptions:
try:
function()
except possible_exception as e:
print("caught", repr(e), "when calling", function.__name__)
prints:
印刷:
caught ValueError() when calling raise_value_error
caught TypeError() when calling raise_type_error
Traceback (most recent call last):
File "run.py", line 14, in <module>
function()
File "run.py", line 8, in raise_index_error
doesnt_exist
NameError: name 'doesnt_exist' is not defined
Of course that leaves you with not knowing what to do when each exception occurs. But since you just want to ignore it and carry on then that's not a problem.
当然,这让您不知道在每个异常发生时该做什么。但既然你只想忽略它并继续,那么这不是问题。
回答by xgqfrms
From issue PY-9715on yourtrack.jetbrains.com:
来自yourtrack.jetbrains.com 上的问题 PY-9715:
From pep-0348:
从pep-0348:
BaseException
The superclass that all exceptions must inherit from. It's name was chosen to reflect that it is at the base of the exception hierarchy while being an exception itself. "Raisable" was considered as a name, it was passed on because its name did not properly reflect the fact that it is an exception itself.
Direct inheritance of BaseException is not expected, and will be discouraged for the general case. Most user-defined exceptions should inherit from Exception instead. This allows catching Exception to continue to work in the common case of catching all exceptions that should be caught. Direct inheritance of BaseException should only be done in cases where an entirely new category of exception is desired.
But, for cases where all exceptions should be caught blindly, except BaseException will work.
基本异常
所有异常都必须继承的超类。选择它的名称是为了反映它位于异常层次结构的基础,同时本身也是一个异常。“Raisable”被认为是一个名字,它被传递是因为它的名字没有正确反映它本身是一个例外的事实。
不期望直接继承 BaseException,并且在一般情况下不鼓励直接继承。大多数用户定义的异常应该从 Exception 继承。这允许在捕获所有应该捕获的异常的常见情况下继续捕获异常。仅在需要全新的异常类别的情况下才应直接继承 BaseException。
但是,对于应该盲目捕获所有异常的情况,BaseException 除外。
回答by Piotr Karnasiewicz
I think in some rare cases catching general exception is just justified and there is a way to trick PEP8 inspection:
我认为在一些罕见的情况下,捕获一般异常是合理的,并且有一种方法可以欺骗 PEP8 检查:
list_of_functions = [f_a,f_b,f_c]
for current_function in list_of_functions:
try:
current_function()
except (ValueError, Exception):
print(traceback.format_exc())
You can replace ValueError
by any other. It works for me (at least in PyCharm).
您可以用ValueError
任何其他替换。它对我有用(至少在 PyCharm 中)。