在上下文管理器装饰方法中默默忽略异常

问题描述 投票:0回答:1

以下代码似乎不会引发。这是一个错误还是我没有正确理解上下文管理器中的错误处理?

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

并且没有例外......

python exception error-handling contextmanager
1个回答
0
投票

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
必须省略,否则不会引发异常。

© www.soinside.com 2019 - 2024. All rights reserved.