在Python中异常处理程序中捕获异常的最简单方法

时间:2017-11-10 05:05:28

标签: python exception exception-handling

在Python程序中,通常使用try-except块捕获异常:

try:
    # Do stuff
except ValueError:
    # Handle exception

我知道在异常处理程序中捕获异常的最好方法是嵌套的try-except块。但是,对于许多嵌套的try-catch块,这可能会有点混乱:

try:
    # Some assignment that throws an exception if the object is not in the list
    try:
        # Some assignment function that throws an exception if the the object is not already in the database
        # Error Handling
    except ValueError:
        try:
            # Some function that throws an exception if the object does not have an undesired property
            # Error Handling
        except AttributeError:
            try:
                # Some function that throws an exception if an error happens
            except Exception:
                # Exception handling
except ValueError:
    # Exception handling

有更简洁的方法吗?类似的东西:

try:
   # Some assignment that throws an exception if the object is not in the list
   try:
       # Some assignment function that throws an exception if the object is not already in the database
   except ValueError:
       # Some function that throws an exception if the object does not have an undesired property
   exceptexcept AttributeError:
       # Some function that throws an exception if an error happens
   exceptexcept Exception:
       # Exception handling 
except ValueError:
   # Exception handling

2 个答案:

答案 0 :(得分:1)

这听起来像一个循环,你想继续尝试,直到你成功或用完选项。所以你可以用这种方式实现它,例如像这样的东西

# Each pair contains a function to call and an exception that can be caught.
# If that exception is raised, the next function will be tried.
action_list = [
    (get_from_list, ValueError),  # throws ValueError if item can't be retrieved
    (get_from_database, ValueError),  # throws ValueError if item can't be retrieved
    (get_from_object, AttributeError),  # throws AttributeError if item lacks desired property
]

result = None
for action, ex in action_list:
    try:
        result = action(key)
        break
    except ex:
        continue

您可以通过让所有帮助函数引发一个自定义异常(例如“NotFound”)来稍微整理一下,然后将其用作检查下一级别的信号,如下所示:

# actions to try; all raise NotFound if unsuccessful
action_list = [
    get_from_list, get_from_database, get_from_object
]

result = None
for action in action_list:
    try:
        result = action(key)
        break
    except NotFound:
        continue

或者您可以将所有步骤放在一个成功返回的函数中。这样,您的分配可以在常规代码中完成,而不是使用辅助函数:

def get_value(key):

    try:
        return some_list[int(key)]
    except ValueError:
        pass

    try:
        return get_from_database(key)
    except ValueError:
        pass

    try:
        return getattr(some_object, key)
    except AttributeError:
        pass

    return None

如果您不想要其他功能,可能会滥用for循环:

result = None
for _ in range(1):

    try:
        result = some_list[int(key)]
        break
    except ValueError:
        pass

    try:
        result = get_from_database(key)
        break
    except ValueError:
        pass

    try:
        result = getattr(some_object, key)
        break
    except AttributeError:
        pass

或者您可以将单个外部try / except与自定义Found例外一起用作“structured goto”:

result = None
try:
    try:
        result = some_list[int(key)]
        raise Found
    except ValueError:
        pass
    try:
        result = get_from_database(key)
        raise Found
    except ValueError:
        pass
    try:
        result = getattr(some_object, key)
        raise Found
    except AttributeError:
        pass
except Found:
    pass  # all good

或者这是一个尝试但真实的结构:

result = None
if result is None:
    try:
        result = some_list[int(key)]
    except ValueError:
        pass
if result is None:
    try:
        result = get_from_database(key)
    except ValueError:
        pass
if result is None:
    try:
        result = getattr(some_object, key)
    except AttributeError:
        pass

答案 1 :(得分:0)

是肯定的。您可以在python中使用异常层次结构。 应该按照例外的顺序小心。捕获错误的除外将被执行,其余全部被忽略。

DO,

inspect.getclasstree(inspect.getmro(Exception))

 BaseException
... Exception
...... StandardError
......... TypeError
......... ImportError
............ ZipImportError
......... EnvironmentError
............ IOError
............... ItimerError
............ OSError
......... EOFError
......... RuntimeError
............ NotImplementedError
......... NameError
............ UnboundLocalError
......... AttributeError
......... SyntaxError
............ IndentationError
............... TabError
......... LookupError
............ IndexError
............ KeyError
............ CodecRegistryError
......... ValueError
............ UnicodeError
............... UnicodeEncodeError
............... UnicodeDecodeError
............... UnicodeTranslateError
......... AssertionError
......... ArithmeticError
............ FloatingPointError
............ OverflowError
............ ZeroDivisionError
......... SystemError
............ CodecRegistryError
......... ReferenceError
......... MemoryError
......... BufferError