Python : 使用来自其他函数的 WITH(上下文管理器)

Python : Use a WITH (context manager) from an other function

我想使用来自其他函数的 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()

你需要将它包裹在另一个暴露 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()