この例を見てみましょう:
with mycontextmanager(arg1='value', arg2=False):
print 'Executed'
引数に基づいてコンテキスト マネージャ内でコード ブロック () を実行しない方法はありますか? たとえば、arg2 が False でない場合は?print 'Executed'
この例を見てみましょう:
with mycontextmanager(arg1='value', arg2=False):
print 'Executed'
引数に基づいてコンテキスト マネージャ内でコード ブロック () を実行しない方法はありますか? たとえば、arg2 が False でない場合は?print 'Executed'
もう 1 つのオプションは、メソッドが条件付きで例外を発生させるアクションを返す特別な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 で取得した値を公開する "whatever" プロパティをサポートしていると仮定します。
with mycontextmanager(arg1='value', arg2=False) as ctx:
if ctx.whatever:
print 'Executed'