時々、何もしないダミーのコンテキストマネージャーが必要です。その後、より便利ですがオプションのコンテキストマネージャーの代用として使用できます。例えば:
ctx_mgr = <meaningfulContextManager> if <condition> else <nullContextManager>
with ctx_mgr:
...
このような些細な空のコンテキストマネージャを定義するにはどうすればよいですか? Pythonライブラリは既製のものを提供しますか?
as
句でコンテキストを使用したい場合はどうですか?
with ctx_mgr as resource:
<operations on resource>
Python 3.7以降: _contextlib.nullcontext
_ を使用します。この理由のために特別に設計されています。
Python 3.7より前では、標準ライブラリはこれらのユースケース専用に設計されたコンテキストマネージャを提供していませんが、いくつかの回避策があります。
以来、Python 3.4、 _contextlib.suppress
_ はその目的に使用できます最初のケース、つまりas
句がない場合:
_ctx_mgr = <meaningfulContextManager> if <condition> else contextlib.suppress()
with ctx_mgr:
...
_
Python 3.3)から、同様の回避策も利用可能です _contextlib.ExitStack
_ 、suppress
よりも遅いですが(テストでは2倍の時間がかかります)。
Before Python 3.3)、またはas
節Python 3.7、開発者は独自に展開する必要があります。以下に実装例を示します。 :
_class NullContextManager(object):
def __init__(self, dummy_resource=None):
self.dummy_resource = dummy_resource
def __enter__(self):
return self.dummy_resource
def __exit__(self, *args):
pass
_
次に書くことができます:
_ctx_mgr = <meaningfulContextManager> if <condition> else NullContextManager(dummy_resource)
with ctx_mgr as resource:
<operations on resource>
_
もちろん、_dummy_resource
_は、「意味のある」リソースに必要なすべての操作をサポートする必要があります。したがって、たとえば、__enter__()
の意味のあるコンテキストマネージャーが、マネージブロック内のquack()
に対して行われた何かを返す場合、_dummy_resource
_もサポートする必要があります。おそらく何もせずに。
_class DummyDuck(object):
def quack()
# Ssssh...
pass
ctx_mgr = <meaningfulContextManager> if <condition> else NullContextManager(DummyDuck())
with ctx_mgr as someDuck:
someDuck.quack()
_
出典: A Python機能リクエスト 。その議論に貢献してくれたすべての人に感謝します。これは、自己回答の質問でその結果を要約する私の試みです。長いスレッドを読む時間を節約してください。また、Pythonドキュメントの このExitStack
の使用 を参照してください。
Python 3.6以下、2.7を含む)の簡単なソリューション:
from contextlib import contextmanager
@contextmanager
def nullcontext(enter_result=None):
yield enter_result
Python 3.7なので、提供されている contextlib.nullcontext
代わりに。
Python 3.2、memoryview(b'')
はno-opコンテキストマネージャとして使用できます。 https://docs.python.org/3/library/ stdtypes.html#memoryview.release 。
長所
インポート不要
3.2以降で動作します
contextlib.nullcontext
の約2倍の速度
短所
# no-op
コメントを追加する必要があります。