在 Python 的异常处理程序中捕获异常的更简洁的方法
Neater way to catch exception in exception handler in Python
在 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
是的。您可以在 python 中使用异常层次结构。
应该注意异常的顺序。捕获到错误的except将被执行,其余的将被忽略。
做,
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
这听起来像是一个循环,您要不断尝试直到成功或 运行 没有选择。所以你可以那样实现它,例如,像这样的东西
# 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
或者您可以将所有步骤放在一个函数中,returns 一旦它成功。这样您的作业就可以用常规代码完成,而不是使用辅助函数:
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
或者您可以使用带有自定义 Found
异常的单个外部 try
/except
作为“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
在 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
是的。您可以在 python 中使用异常层次结构。 应该注意异常的顺序。捕获到错误的except将被执行,其余的将被忽略。
做,
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
这听起来像是一个循环,您要不断尝试直到成功或 运行 没有选择。所以你可以那样实现它,例如,像这样的东西
# 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
或者您可以将所有步骤放在一个函数中,returns 一旦它成功。这样您的作业就可以用常规代码完成,而不是使用辅助函数:
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
或者您可以使用带有自定义 Found
异常的单个外部 try
/except
作为“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