以下代码似乎不会引发。这是一个错误还是我没有正确理解上下文管理器中的错误处理?
from contextlib import contextmanager
class Dataset:
_getToRaise = False
def __getitem__(self, index):
if self._getToRaise:
print("It is supposed to raise here")
raise ValueError
return 0
@contextmanager
def getToRaise(self):
try:
self._getToRaise = True
print('Entering context manager')
yield
finally:
print('Exiting context manager')
self._getToRaise = False
return
d = Dataset()
with d.getToRaise():
d[0]
在 Python 3.8.17 中运行代码返回:
Entering context manager
It is supposed to raise here
Exiting context manager
并且没有例外......
contextlib.contextmanager
的文档指出:
[Y]您可以使用 try... except...finally 语句来捕获错误(如果 任何),或确保进行一些清理。如果有例外情况 被困只是为了记录它或执行某些操作(而不是 而不是完全抑制它),生成器必须重新提高该值 例外。否则生成器上下文管理器将指示 with语句表明异常已被处理,并执行 将继续执行 with 之后的语句 声明。
这意味着生成器必须重写为:
@contextmanager
def getToRaise(self):
try:
self._getToRaise = True
print('Entering context manager')
yield
except: # If exception
raise # reraise
finally:
print('Exiting context manager')
self._getToRaise = False
# return
最后的
return
必须省略,否则不会引发异常。