sha*_*l85 8 python contextmanager
我是否可以拥有一个偶尔不会产生的上下文管理器,在这种情况下,with语句中的代码根本不会被执行?
import contextlib
@contextlib.contextmanager
def MayNotYield(to_yield):
if to_yield:
yield
with MayNotYield(True):
print 'This works.'
with MayNotYield(False):
print 'This errors.'
Run Code Online (Sandbox Code Playgroud)
我可以要求用户使用try-catch包装with语句,但这不是首选.我也可以做以下但它也很难看.
import contextlib
@contextlib.contextmanager
def AlwaysYields(to_yield):
if to_yield:
yield 1
else:
yield 2
with AlwaysYields(True) as result:
if result == 1:
print 'This works.'
Run Code Online (Sandbox Code Playgroud)
另一种选择是只使用常规生成器而不是上下文管理器;普通的发电机不会有这个限制。但是您必须将它与“for”构造一起使用,而不是使用“with”:
def MayNotYield(to_yield):
if to_yield:
yield
for _ in MayNotYield(True):
print('This prints.')
for _ in MayNotYield(False):
print('This does not.')
Run Code Online (Sandbox Code Playgroud)
不幸的是,上下文管理器协议没有给上下文管理器一个说"不要运行with块"的方法(除了引发异常__enter__).如果您正在使用上下文管理器,我认为您的第二种方法是__enter__返回一个值来表示是否应该运行该块是最好的方法.如果由于某些其他原因不需要上下文管理器,则可以使用简单的if语句:
if do_stuff:
# do the stuff
Run Code Online (Sandbox Code Playgroud)