Python 收集所有错误并引发减少的异常

Python 收集所有错误并引发减少的异常,python,Python,问题很简单,看起来很一般。我将收集一些操作中的所有错误,并将它们全部显示给用户 我的问题是:有没有这种模式的公共库实现 考虑下面的例子。我需要一个MyClass对象的集合。创建此对象可能会失败,因此示例代码可能如下所示: class MyError(Exception): pass class MyClass: def __init__(self, foo, bar): if foo % 2 == 0: raise MyError('U

问题很简单,看起来很一般。我将收集一些操作中的所有错误,并将它们全部显示给用户

我的问题是:有没有这种模式的公共库实现

考虑下面的例子。我需要一个MyClass对象的集合。创建此对象可能会失败,因此示例代码可能如下所示:

class MyError(Exception):
    pass


class MyClass:
    def __init__(self, foo, bar):
        if foo % 2 == 0:
            raise MyError('Unable to create object with foo={}, bar={}'.format(
                foo, bar))

        self.foo = foo
第一个示例将在第一个异常上失败,这不是我需要的:

def fail_on_first():
    try:
        return [MyClass(i, None) for i in range(10)]
    except MyError as e:
        raise
下一个代码具有所需的行为:

def collect_all_errors():
    errors = []
    objects = []

    for i in range(10):
        try:
            objects.append(MyClass(i, None))
        except MyError as e:
            errors.append(e)

    if errors:
        raise MyError('\n'.join(e.message for e in errors))

    return objects
但这还不够普遍。让我们试着概括一下:

class Args:
    def __init__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs


def collect_all_errors_generalized(exception_type, callable, argslist):
    errors = []
    objects = []

    for args in argslist:
        try:
            objects.append(callable(*args.args, **args.kwargs))
        except exception_type as e:
            errors.append(e)

    if errors:
        raise exception_type('\n'.join(e.message for e in errors))

    return objects
应用程序代码为:

try:
    objects = collect_all_errors_generalized(
        MyError, MyClass, [Args(i, 'bar') for i in range(10)])
except MyError as e:
    print(e)
或不带参数:

def collect_all_errors_generalized_lambdas(exception_type, callables):
    errors = []
    objects = []

    for callable in callables:
        try:
            objects.append(callable())
        except exception_type as e:
            errors.append(e)

    if errors:
        raise exception_type('\n'.join(e.message for e in errors))

    return objects

def create_factory(mytype, *args, **kwargs):
    return lambda: mytype(*args, **kwargs)

try:
    collect_all_errors_generalized_lambdas(
        MyError, [create_factory(MyClass, i, 'bar')
                  for i in range(10)])
except MyError as e:
    print(e)
因此,问题再次出现:

  • 这是普通模式吗
  • 有什么好的实现或有用的代码片段吗

  • 谢谢。

    首先,我不知道你为什么认为这是个好主意

    关于问题:

    1:不,这不是常见的模式。异常通常用于处理代码问题,有时用于控制流

    2:因为这不是一个好主意,我不认为这是一个好的实现,甚至不是一个有用的片段,无论如何

    这里有一个“通用”修饰符,您可以将其作为要记录的
    exception
    的参数传递

    def exceptloger(exceptions=None):
        def wrapper(func):
            def func_wrapper(*args, **kwargs):
                if 'excepts' not in globals():
                    global excepts
                    excepts = []
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    excpt = e.__class__.__name__
                    if exceptions and excpt in exceptions:
                        excepts.append({excpt: e.message})
                    if exceptions == 'all':
                        excepts.append({excpt: e.message})
            return func_wrapper
        return wrapper
    
    装饰你想要处理的方法

    class MyError(Exception):
        pass
    
    class MyClass(object):
        def __init__(self, foo, bar):
            if not foo % 2:
                raise MyError('Unable to create object with foo={}, bar={}'.format(foo, bar))
    
    @exceptloger('MyError')
    def fail_on_first():
        results = []
        for i in range(10):
            results.append(MyClass(i, None))
        return results
    
    @exceptloger('all')
    def zerodivison():
        return 1 / 
    
    结果

    fail_on_first()
    zerodivison()
    
    print excepts
    
    这里有一个很大的陷阱,即decorator定义了一个全局变量。它可能会失控,所以使用时要小心