with ステートメントは、コンテキスト マネージャーによって定義されたメソッドでブロックの実行をラップするために使用されます。これにより、一般的な try...except...finally の使用パターンをカプセル化して、簡単に再利用できます。
with_stmt ::= "with" ( "(" with_stmt_contents ","? ")" | with_stmt_contents ) ":" suite
with_stmt_contents ::= with_item ("," with_item)*
with_item ::= expression ["as" target]
コンテキスト式 (with_item で指定されたもの) を評価して、コンテキスト マネージャーを取得します。
後で使用するために、コンテキスト マネージャの __enter__() をロードします。
後で使用するために、コンテキスト マネージャの __exit__() をロードします。
コンテキスト マネージャの __enter__() メソッドが呼び出されます。
ターゲットが with ステートメントに含まれている場合、__enter__() の戻り値がそれに割り当てられます。
with ステートメントは、__enter__() メソッドがエラーなしで戻る場合に常に __exit__() が呼び出されることを保証することに注意してください。そのため、ターゲットリストへの割り当て時にエラーが発生した場合、スイート内で発生したエラーと同様に扱われます。以下の手順を参照してください
コンテキスト マネージャの __exit__() メソッドが呼び出されます。例外によってスイートが終了した場合、そのタイプ、値、およびトレースバックが引数として __exit__() に渡されます。それ以外の場合は、3 つの None 引数を指定します。
スイートが例外で終了し、__exit__() メソッドが false を返す場合、例外が再発生します。戻り値が true の場合、例外は抑制され、実行は with ステートメントの次のステートメントから続行されます。
スイートが例外以外の理由で終了した場合、 __exit__() の戻り値は無視され、実行は通常の場所で実行された終了のタイプで続行されます。
次のコード
with EXPRESSION as TARGET:
SUITE
意味的には次と同等です。
manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
hit_except = False
try:
TARGET = value
SUITE
except:
hit_except = True
if not exit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
exit(manager, None, None, None)