Python 2.6では、ネストされたコンテキストマネージャを次のようにフォーマットしていました:
with nested(
context1,
context2
) as a, b:
pass
Python 2.7以降、nested
は非推奨になりました。1行に複数のコンテキストマネージャの例をたくさん見ましたが、それらを複数行で表示します。
# That's working fine
with context1 as a, context2 as b:
pass
# But how do we make it multine?
# These are not working
with (
context1,
context2
) as a, b:
pass
with context1 as a,
context2 as b:
pass
バックスラッシュ文字(
\
)を使用して、2つ以上の物理行を論理行に結合できます。
(明示的な行結合セクションを引用)
コンテキストマネージャを別の行に配置したい場合は、バックスラッシュで行を終了することにより、それを機能させることができます。
with context1 as a,\
context2 as b:
pass
contextlib.ExitStack
他のコンテキストマネージャーとクリーンアップ関数をプログラムで簡単に組み合わせることができるように設計されたコンテキストマネージャー、特にオプションであるか、入力データによって駆動されるもの。
Python 3.3以降で利用可能で、可変数のコンテキストマネージャーを簡単に入力できます。2つのコンテキストマネージャーの場合、使用法は次のようになります。
from contextlib import ExitStack
with ExitStack() as es:
a = es.enter_context(context1)
b = es.enter_context(context2)
コンテキスト式を複数のnestedwith
ステートメントに分割できます。
複数のアイテムがある場合、コンテキストマネージャは、複数のwithステートメントがネストされているかのように処理されます。
with A() as a, B() as b:
スイートは次と同等です
with A() as a: with B() as b: suite
(from withステートメント )
かっこを独創的に使用してバックスラッシュを回避する方法があります。as
の前に式を括弧で囲みます。ただし、あまり目立ちません:
with (
open('/etc/passwd')) as foo, (
open('/tmp/bar')) as bar:
pass # this parses correctly
必要に応じて、さらに入れ子にするのは簡単です。
with context1 as a, \
context2 as b:
pass
他の改行と同様に、バックスラッシュはソリューションを提供します
あなたの例は以下と同等です:
with context1 as a:
with context2 as b:
pass
2行で見栄えがします。
リファレンス: https://docs.python.org/2.7/reference/compound_stmts.html#the-with-statement