1、异常捕获原则:将更精确的except语句放在前面 2、except 异常匹配是从上到下匹配,如果把父类异常类放在前面,则后面的异常永远不会触发 3、使用空raise:如果希望记录某个异常之后将它重新抛出交给上层处理,可使用不带参数的raise
常用写法
def incr_by_one(value: int):
try:
num = value + 1
except (TypeError, ValueError) as e:
print("发生错误了", e)
raise
except Exception as e:
print("Exception Error", e)
else:
print("这是没有抛出异常才会执行的")
finally:
print("调用finally ")
return num
# 这是没有抛出异常才会执行的
# 调用finally
incr_by_one(value=1)
# 发生错误了 must be str, not int
# 调用finally
incr_by_one(value='2')
raise
def test_raise(num: int = 0):
if num <= 0:
raise Exception('num <= 0', num)
else:
print('num > 0')
print("raise没有抛出异常,后面的代码正常执行")
# num > 0
# raise没有抛出异常,后面的代码正常执行
test_raise(num=1)
通过上下文管理器忽略异常处理
"""忽略某个异常
借使用上下文管理器的方式,实现可复用的「忽略异常」功能
"""
class IgnoreSomeException(object):
def __enter__(self): ...
def __exit__(self, exc_type, exc_value, traceback):
print("exc_type=", exc_type, "exc_value=", exc_value, "traceback=", traceback)
if exc_type == ZeroDivisionError:
print('发现 ZeroDivisionError 异常, 跳过处理')
# 返回True,则起到忽略异常的效果,返回False,则会将异常正常抛出
return True
print("没发现 ZeroDivisionError 异常, 正常执行")
return False
# exc_type= <class 'ZeroDivisionError'> exc_value= division by zero traceback= <traceback object at 0x7f3192a816c8>
# 发现 ZeroDivisionError 异常, 跳过处理
with IgnoreSomeException():
1/0
# exc_type= None exc_value= None traceback= None
# 没发现 ZeroDivisionError 异常, 正常执行
with IgnoreSomeException():
1/1
通过contextmanager 处理异常
以 yield 关键字为界,yield之前的逻辑会在进入上下文管理器时执行(相当于enter) yield之后的逻辑会在退出上下文管理器时执行(相当于exit) 如果需要在上下文管理器内捕获异常,必须使用try语法块包裹yield语句
"""
使用contextmanager装饰器 处理异常
contextmanager 可将任意一个生成器函数直接转换为上下文管理器
"""
from contextlib import contextmanager
import sys
@contextmanager
def ignore_exception_with_contextmanager():
try:
1/1
yield False
except ZeroDivisionError as e:
print("ignore ZeroDivisionError :", sys.exc_info())
finally:
print("call finally func")
# ignore ZeroDivisionError : (<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero',), <traceback object at 0x7fc077b24c48>)
# call finally func
with ignore_exception_with_contextmanager():
print(1/0)