【问题标题】:Can I retrieve the return value of __exit__ from a python context manager?我可以从 python 上下文管理器中检索 __exit__ 的返回值吗?
【发布时间】:2017-09-06 07:53:51
【问题描述】:

我在 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

那么我如何访问在我的 with 块之后(或末尾)从__exit__ 返回的 my_results。在 __exit__ 方法中返回 True 以外的内容是否合法?

【问题讨论】:

    标签: python with-statement contextmanager


    【解决方案1】:

    __exit__ 方法中返回 True 以外的东西是否合法?

    不,不是真的,但 Python 只会测试truth value,所以你可以侥幸逃脱。换句话说,如果你在这里返回一个真实的对象,任何异常都会被抑制。如果没有异常,返回一个真值只是一个空操作。

    如何访问我的 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() context manager 共享捕获的异常的方式,例如。

    【讨论】:

    • 非常感谢!有用的信息! :) 我不知道 MyContextManager 的实例在 with 块之后仍然存在。
    最近更新 更多