我能否从Python上下文管理器中检索__exit__的返回值?

4
我在Python中使用上下文管理器。我希望从我的__exit__方法中获取一些日志。因此,我的代码记录了如下内容:
class MyContextManager:
    def __init__(self, value1, value2)
        self.value1 = value1
        self.value2 = value2

    def __enter__(self)
        # Do some other stuff
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # Do some tear down action, process some data that is 
        # created in __enter__ and log those results
        return my_results

with MyContextManager(value1=my_value1, value2=my_value2) as manager:
     # Do some stuff

那么我怎么才能访问从 __exit__ 返回的 my_results,在我的 with 语句块结束后(或在末尾)呢? 在 __exit__ 方法中返回 True 以外的内容合法吗?

1个回答

8

__exit__ 方法中返回除 True 以外的内容是否可行?

实际上不行,但是 Python 只会测试真值,所以你可以这么做。换句话说,如果你在这里返回一个真值对象,任何异常都将被抑制。如果没有异常,返回真值只是一个无操作。

我如何在 with 块之后(或结束时)访问从 __exit__ 返回的 my_results?

你不能。 with 表达式机制已经消耗了它。

你应该以其他方式使其可用;将其设置为上下文管理器对象本身的属性:

class MyContextManager:
    def __init__(self, value1, value2)
        self.value1 = value1
        self.value2 = value2

    def __enter__(self)
        # Do some other stuff
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # Do some tear down action, process some data that is 
        # created in __enter__ and log those results
        self.my_results = my_results
        # returning None, we don't want to suppress exceptions
        return None

with MyContextManager(value1=my_value1, value2=my_value2) as manager:
     # Do some stuff

results = manager.my_results

manager名称在with块完成后可用。

例如,这就是unittest.TestCase.assertRaises()上下文管理器共享捕获异常的方式。


非常感谢!信息很有帮助! :) 我不知道 MyContextManager 的实例在 with 块之后仍然存在。 - Lennart Weitzenberger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接