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