PythonでのWithの使い方

4742 ワード

Dive Into Pythonの記述ファイルを見てその章を読み書きしたとき、withの使い方を見て、関連資料を調べて、後で使うために記録しました.
 
公式のreferenceではwith statementについて、Withはcontext managerによって定義された方法の実行ブロックを包装することを明らかにした.これでtryを...except...finallyの使用モードはカプセル化されてから再利用しやすい.
公式の定義は以下の通りです.
1 with_stmt ::=  "with" with_item ("," with_item)* ":" suite
2 with_item ::=  expression ["as" target]

「item」のwith申明の実行過程は以下の通りである.
  • は、with_itemで与えられたexpression.
  • コンテンツマネージャ(context manager)ロード_exit__()方法は、
  • の使用に備える
  • コンテンツマネージャトリガ_enter__()メソッド
  • ターゲット(with_item)がwith申明に含まれている場合、_enter__()の戻り値は、ターゲットに割り当てられます.注意:With申明保証の場合_enter__()関数の実行にエラーはありません.exit__()は常に実行されます.ターゲットへの付与中にエラーが発生した場合、このエラーは実行プログラムグループで発生したものとみなされます.第6ステップ
  • 参照
  • 実行プログラムグループ
  • コンテンツマネージャの_exit__()メソッドがトリガーされます.プログラムグループに異常またはエラーが発生した場合、対応するtype、value、およびtracebackはすべて入力されます.exit__()メソッドで行きます.そうでなければ、3つのNone値がメソッドに入力されます.

  • プログラムグループで例外により終了した場合exit__()の戻り値が偽であると、異常が再開されます.戻り値が真の場合、例外を無視してWith宣言後のプログラムを実行します.
    プログラムグループに異常終了がない場合は無視_exit__()の戻り値、何をすべきか.
    複数のターゲット(with_item)がwith申明にある場合、コンテンツマネージャ(context manager)はそれを複数のwith申明ネストと見なす.例は次のとおりです.
    1 with A() as a, B() as b:
    2     suite

    以下と同じです.
    1 with A() as a:
    2     with B() as b:
    3         suite

    以上がWith申明の具体的な内部実行過程であり、その中で最も核心的なのはコンテンツマネージャ(context manager)であることがわかるので、with申明のコンテンツマネージャ(with statment context managers)に関する内容を調べた.
    Context Managerは、主にwith宣言で定義されたランタイムコンテンツ(runtime context)を管理するために使用されます.このマネージャは、2つの方法を実装しています.1つは__です.enter__()メソッド、1つは_exit__()メソッド.
    __enter__()メソッドは、主にランタイムコンテンツ(runtime context)に入り、それに対応するオブジェクトを返します.このメソッドの戻り値は、context Managerのwithを使用してAS識別子を明示した後の内容にバインドされます.例を挙げます.
    1 with open(r'D:/test.txt', 'r', encoding='utf-8') as a_file:
    2     process(a_file)

    コンテンツマネージャの__enter__()メソッドは、a_に付与されたファイルオブジェクトを返します.file.
    例えば、浮動小数点型データ演算では、精度、キャリーのルールを設定し、どのような状況が異常とみなされるかを決定し、指数範囲を制限する計算環境(contexts)を設定する必要がある.getcontext()とsetcontext()メソッドを使用して実装してもよいし、localcontext()とwith宣言を組み合わせたメソッドを使用して実装してもよい.
    1 from decimal import localcontext
    2 
    3 with localcontext() as ctx:
    4     ctx.prec = 42   # Perform a high precision calculation
    5     s = calculate_something()
    6 s = +s  # Round the final result back to the default precision

    __exit__(exc_type,exc_val,exc_tb)メソッドは、このランタイムコンテンツまたは環境(runtime context)を終了し、途中で発生した例外を無視するかどうかを決定するために、ブール値の変数を返します.途中でwith申明中の執行体に何か問題が発生した場合.対応する異常タイプ,値および遡及情報がこのメソッドに伝達され,異常がなければNoneに伝達される.異常入力があり、ブール値が真の場合、異常入力があるがブール値が偽の場合、異常は無視されます.コンテンツマネージャのメリットは、前述したようにtryを...except...finallyの使用モードはカプセル化されてから再利用しやすい.
    contextlibに関する内容は後で更新されます.