web-dev-qa-db-ja.com

Python複数行にネストされたコンテキストマネージャ

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
26
Simon Boudrias

バックスラッシュ文字

バックスラッシュ文字(\)を使用して、2つ以上の物理行を論理行に結合できます。

明示的な行結合セクションを引用)

コンテキストマネージャを別の行に配置したい場合は、バックスラッシュで行を終了することにより、それを機能させることができます。

with context1 as a,\
     context2 as b:
    pass

contextlib.ExitStack

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ステートメント

24
vaultah

かっこを独創的に使用してバックスラッシュを回避する方法があります。asの前に式を括弧で囲みます。ただし、あまり目立ちません:

with (
  open('/etc/passwd')) as foo, (
  open('/tmp/bar')) as bar:
  pass  # this parses correctly

必要に応じて、さらに入れ子にするのは簡単です。

8
9000
with context1 as a, \
context2 as b:
pass

他の改行と同様に、バックスラッシュはソリューションを提供します

2
Sudeep Juvekar

あなたの例は以下と同等です:

with context1 as a:
    with context2 as b:
        pass

2行で見栄えがします。

リファレンス: https://docs.python.org/2.7/reference/compound_stmts.html#the-with-statement

2
Robᵩ