【问题标题】:Python : Use a WITH (context manager) from an other functionPython:使用来自其他函数的 WITH(上下文管理器)
【发布时间】:2020-07-23 11:51:21
【问题描述】:

我想使用来自其他函数的 with 语句 不幸的是,如果我产生它的值,它被认为是一个生成器,我不能将它用作调用函数中的上下文管理器

class Something:
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

    def do_something(self):
        pass

    def do_something_else(self):
        pass


def inner_context_manager():
    with Something() as a:
        a.do_something()
        yield a


def test_inner_context_manager():
    with inner_context_manager() as b:  # NOT WORKING -> AttributeError: __enter__
        b.do_something_else()

    for b in inner_context_manager():  # WORKING
        b.do_something_else()

【问题讨论】:

  • 您的意思是使用contextlib.contextmanager 装饰器吗?您看起来像是模仿了使用装饰器但没有装饰器的代码。
  • 谢谢,太好了,我正在更新答案!

标签: python generator contextmanager


【解决方案1】:

您需要将其包装在暴露 enter 的其他对象中,如下所示:

def inner_context_manager():
    class Wrapper(Something):
        def __enter__(self):
            tmp = super(Wrapper, self).__enter__()
            tmp.do_something()
            return tmp

        def __exit__(self, exc_type, exc_val, exc_tb):
            super(Wrapper, self).__exit__(exc_type, exc_val, exc_tb)

    return Wrapper()


def test_user_inner_context_manager():
    with inner_context_manager() as b:
        b.do_something_else()

或者只是添加装饰器contextlib.contextmanager:

@contextmanager
def inner_context_manager():
    with Something() as a:
        a.do_something()
        yield a

def test_user_inner_context_manager():
    with inner_context_manager() as b:
        b.do_something_else()

【讨论】:

    猜你喜欢
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 2019-05-30
    • 2013-10-25
    相关资源
    最近更新 更多