让我们看看这个例子:
with mycontextmanager(arg1='value', arg2=False):
print 'Executed'
有没有办法在基于参数的上下文管理器中不执行代码块( ),例如:当 arg2 不为 False 时?print 'Executed'
让我们看看这个例子:
with mycontextmanager(arg1='value', arg2=False):
print 'Executed'
有没有办法在基于参数的上下文管理器中不执行代码块( ),例如:当 arg2 不为 False 时?print 'Executed'
另一种选择是使用特殊的ConditionalExecution
上下文管理器,其__enter__
方法返回有条件地引发SkipExecution
异常的操作。该__exit__
方法仅抑制此异常。类似于以下内容:
class SkipExecution(Exception): pass
class ConditionalExecution(object):
def __init__(self, value, arg):
self.value = value
self.arg = arg
def __enter__(self):
def action():
if not self.arg:
raise SkipExecution()
return action
def __exit__(self, exc_type, exc_value, tb):
if exc_type is SkipExecution:
return True
return False
用作:
In [17]: with ConditionalExecution(1, True) as check_execution:
...: check_execution()
...: print('Hello')
...:
Hello
In [18]: with ConditionalExecution(1, False) as check_execution:
...: check_execution()
...: print('Hello')
In [19]:
但是问题是您必须添加对返回值的调用。
问题是当且仅当__exit__
成功返回时才调用它,这意味着您不能引发异常来阻止代码块的执行。如果您愿意,您可以修改此解决方案,以便可以在第一行完成调用,例如: __enter__
__enter__
check_execution()
In [29]: with ConditionalExecution(1, True) as check_execution, check_execution():
...: print('Hello')
Hello
In [30]: with ConditionalExecution(1, False) as check_execution, check_execution():
...: print('Hello')
使用Skipper
帮助上下文管理器:
class SkipExecution(Exception): pass
class Skipper(object):
def __init__(self, func):
self.func = func
def __call__(self):
return self.func() or self
def __enter__(self):
return self
def __exit__(self, *args):
pass
class ConditionalExecution(object):
def __init__(self, value, arg):
self.value = value
self.arg = arg
def __enter__(self):
def action():
if not self.arg:
raise SkipExecution()
return Skipper(action)
def __exit__(self, exc_type, exc_value, tb):
if exc_type is SkipExecution:
return True
return False
我认为没有至少像上面的示例中那样的显式函数调用,无论如何都无法做到这一点。
也许像这样,假设您的上下文管理器支持“任何”属性,该属性会在初始化时公开它在 arg2 中获得的值:
with mycontextmanager(arg1='value', arg2=False) as ctx:
if ctx.whatever:
print 'Executed'