python - Try...除了多个独立的语句外,执行尽可能多的语句

标签 python exception

我想执行多个函数,收集它们的异常(如果有),并引发复合异常,调用尽可能多的函数,而不会在出现异常后中断。例如,假设我有

def f():
    do_one()
    do_two()
    do_three()

do_i 函数不依赖于彼此的状态。做我想做的事情的最明显的方法是:

def f():
    errors = []
    for do_i in [do_one, do_two, do_three]:
        try:
            do_i()
        except Exception as e:
            errors.append(e)
    if errors:
        raise Exception(';'.join(errors))

或者稍微好一点:

def catch_error(arr, f, *args, **kwargs):
    try:
        return f(*args, **kwargs)
    except Exception as e:
        arr.append(e)
        return None

def f():
    errors = []
    for do_i in [do_one, do_two, do_three]:
        catch_error(errors, do_i)
    if errors:
        raise Exception(';'.join(errors))

但这仍然很丑陋。有没有一种我所缺少的 Pythonic 方法可以做到这一点,也许可以巧妙地使用 with 语句?

编辑:在理想的世界中,Python 会有这样的:

errors = []
awesome_block(errors):
    do_one()
    do_two()
    do_three()
return 'yes!' if not errors else ';'.join(map(str, errors))

最佳答案

您可以将函数重写为上下文管理器,这确实会稍微简化您的代码。我保留了传递列表的约定,尽管这会产生内部列表,以便您稍后可以使用它。

from contextlib import contextmanager

@contextmanager
def catch_errors(error_list=None):
    error_list = error_list if error_list is not None else []
    try:
        yield error_list
    except Exception as e:
        error_list.append(e)

error_list = []
with catch_errors(error_list):
    raise Exception("First exception")
with catch_errors(error_list):
    raise ValueError("Second exception")

if error_list:
    raise Exception(";".join(map(repr, error_list)))

我认为这里的reprstr更有用。 @contextmanager 允许在 with 语句中使用,而您只需将函数编写为生成器。

如果您没有将列表传递给生成器,那么您需要跟踪返回的列表。

with catch_errors() as errors1:
     raise Exception("First exception")
print errors1 # Exception("First exception",)

关于python - Try...除了多个独立的语句外,执行尽可能多的语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17287849/

相关文章:

python - Scrapy 蜘蛛 : Restart spider when finishes

python - 从服务器上运行的 python 线程将数据推送到远程客户端

python - 如何使用 QSignalMapper 和动态创建的 QActions ?

java - 我怎么知道可以从方法中抛出哪些异常?

c++ - 从 std::exception 继承的正确方法

c# - C# 错误处理练习中的 throw 关键字负责什么

ruby-on-rails - 禁用rails中所有html异常渲染

python - 为什么python会在大指数结果的末尾添加一个 'L'?

python - Django 压缩错误 : Invalid input of type: 'CacheKey'

java - 试图连接到 tomcat6 : java.net.UnknownHostException 上的 mysql 服务器