raise ValueError('A very specific bad thing happened.')
避免抛出通用异常
避免使用通用的 Exception ,因为捕获它会捕获所有子类异常,可能会隐藏潜在的错误。
1 2 3 4 5 6 7 8 9 10 11 12
# 不建议的做法 raise Exception('I know Python!')
# 示例代码 defdemo_bad_catch(): try: raise ValueError('Represents a hidden bug, do not catch this') raise Exception('This is the exception you expect to handle') except Exception as error: print('Caught this error: ' + repr(error))
demo_bad_catch()
最佳实践:raise 语句
使用最具体的异常构造函数,并可传递任意数量的参数。
1 2 3 4 5 6
raise ValueError('A very specific bad thing happened', 'foo', 'bar', 'baz')
try: some_code_that_may_raise_our_value_error() except ValueError as err: print(err.args)
最佳实践:except 子句
在 except 子句中,使用无参数的 raise 语句重新抛出异常,以保留堆栈跟踪信息。
1 2 3 4 5 6 7 8 9
import logging
logger = logging.getLogger(__name__)
try: do_something_in_app_that_breaks_easily() except AppError as error: logger.error(error) raise
Python 3中的异常链
在Python 3中,可以使用 from 关键字实现异常链,保留堆栈跟踪信息。
1
raise RuntimeError('specific message') from error
创建自定义异常
如果需要表示应用程序中特定的错误情况,可以创建自定义异常类。
1 2 3 4 5
classMyAppLookupError(LookupError): '''raise this when there's a lookup error for my app'''
if important_key notin resource_dict andnot ok_to_be_missing: raise MyAppLookupError('resource is missing, and that is not ok.')
核心代码
抛出异常示例
1 2 3 4 5 6 7 8 9 10 11
# 抛出带参数的异常 try: raise ValueError("I have raised an Exception") except ValueError as exp: print("Error", exp)
try: result = a / b print(result) except Exception: somefunction() raise
异常链示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classMyCustomException(Exception): pass
a = 10 b = 0 result = None try: try: result = a / b except ZeroDivisionError as exp: print("ZeroDivisionError -- ", exp) raise MyCustomException("Zero Division ") from exp except MyCustomException as exp: print("MyException", exp) print(exp.__cause__)