在这种情况下如何防止“过于宽泛的异常”?

时间:2015-05-25 16:14:25

标签: python exception pep8

我得到了一个可能失败的功能列表,如果一个失败,我不希望脚本停止,而是继续下一个功能。

我用这样的东西执行它:

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())

它工作正常,但它不符合PEP8:

  

捕获异常时,请及时提及特定异常   可能而不是使用bare except:子句。

     

例如,使用:

try:
    import platform_specific_module
except ImportError:
    platform_specific_module = None
     

一个裸的except:子句将捕获SystemExit和KeyboardInterrupt   异常,使用Control-C更难中断程序,   并且可以掩饰其他问题。如果你想捕获所有异常   那个信号程序错误,使用除了Exception :(除了是   相当于除了BaseException:)。

     

一个好的经验法则是将裸'除了'子句的使用限制为两个   例:

     

如果异常处理程序将打印出来或记录回溯;至少用户会意识到发生了错误。

     

如果代码需要做一些清理工作,但是然后让异常向上传播并加注。试试......终于可以更好了   处理这种情况的方法。

这是怎样的好方法?

7 个答案:

答案 0 :(得分:23)

您引用的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)

答案 1 :(得分:1)

// youtrack.jetbrains.com/issue/PY-9715

  

PY-9715不一致"过于宽泛的例外条款"检查   ["过于宽泛的例外条款"检查] [1]

// legacy.python.org/dev/peps/pep-0348 /

  

BaseException

     

所有异常必须从中继承的超类。它的名字是   选择反映它是异常层次结构的基础   虽然本身就是例外。 "可升高"被认为是一个名字,   它被传递,因为它的名字没有恰当地反映这一事实   它本身就是一个例外。

     

不期望直接继承BaseException,并且将是   对一般情况感到沮丧。大多数用户定义的异常应该   继承自Exception。这允许捕获异常   继续在捕获所有异常的常见情况下工作   应该抓住。 BaseException的直接继承应该只是   在需要一类全新例外的情况下完成。

     

但是,对于所有例外都应盲目抓住的情况,除外   BaseException将起作用。

[1] http://i.stack.imgur.com/8UByz.png

// youtrack.jetbrains.com/issue/PY-9715

// legacy.python.org/dev/peps/pep-0348 /

答案 2 :(得分:1)

如果重新引发异常,则可以避免该错误。这样,您就可以进行损害控制,而不会危害其发生的松动。

答案 3 :(得分:1)

用它来欺骗 PEP8:

try:
    """code"""

except (Exception,): 
    pass

答案 4 :(得分:0)

您是否意味着每个功能都可以引发不同的异常?当您在except子句中命名异常类型时,它可以是引用异常的任何名称,而不仅仅是类名。

例如

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__)

打印:

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

当然,这会让您在发生每个异常时不知道该怎么做。但是既然你只是想忽略它并继续下去,那就不是问题了。

答案 5 :(得分:0)

我认为在极少数情况下捕获一般异常是合理的,并且有一种方法可以欺骗PEP8检查:

dart:html

您可以将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()) 替换为其他任何内容。它对我有用(至少在PyCharm中)。

答案 6 :(得分:0)

您可以输入一条实际上对我有用的评论,例如except Exception as error: # pylint: disable=broad-except。希望对您有用。