Pythonのwithステートメントを理解しようとしています。どこを見ても、ファイルの開閉について説明しており、try-finallyブロックを置き換えることを目的としています。誰かが他の例も投稿できますか?私はちょうどフラスコを試しています、そしてそれにたくさんの声明があります。確かに誰かにそれについていくらかの明確さを提供するように要求してください。
3 に答える
ここに非常に良い説明があります。基本的に、withステートメントは、関連付けられたオブジェクトに対して2つの特別なメソッドを呼び出します。__enter__および__exit__メソッド。enterメソッドは、「with」ステートメントに関連付けられた変数を返します。ステートメントの実行後に__exit__メソッドが呼び出され、クリーンアップ(ファイルポインターのクローズなど)が処理されます。
このwith
声明の目的は、「正しいことをする」ことを最も抵抗の少ない道にすることです。ファイルの例は最も単純ですが、スレッドロックは実際には明らかにバグのないコードのより古典的な例を提供します。
try:
lock.acquire()
# do stuff
finally:
lock.release()
このコードは壊れています-ロックの取得が失敗した場合、間違った例外がスローされます(コードは取得したことのないロックを解放しようとするため)、さらに悪いことに、これが再帰的なロックの場合は解放されます早い。正しいコードは次のようになります。
lock.acquire()
try:
# do stuff
finally:
# If lock.acquire() fails, this *doesn't* run
lock.release()
ステートメントを使用するwith
と、コンテキストマネージャーに組み込まれているため、これを誤解することは不可能になります。
with lock: # The lock *knows* how to correctly handle acquisition and release
# do stuff
ステートメントが大いに役立つ他の場所は、with
関数とクラスのデコレータの主な利点に似ています。「2ピース」のコードが必要であり、任意の数のコード行で区切ることができます(デコレータの関数定義try
、現在のケース)そしてそれを「ワンピース」コードに変換し、プログラマーは単に彼らがやろうとしていることを前もって宣言します。
短い例では、これは大きな利益のようには見えませんが、実際にはコードをレビューするときに大きな違いがあります。コードの一部を見るlock.acquire()
と、下にスクロールして対応するを確認する必要がありますlock.release()
。しかし、私が見るwith lock:
と、そのようなチェックは必要ありません-ロックが正しく解放されることがすぐにわかります。
ファイルを開く例を含め、with
PEP343での使用例は12あります。
- ブロックの開始時に取得されたロックが、ブロックが離れたときに解放されるようにするためのテンプレート
- ブロックが残されたときにファイルが閉じられることを保証するファイルを開くためのテンプレート
- データベーストランザクションをコミットまたはロールバックするためのテンプレート
- 例1ジェネレータなしで書き直された
- stdoutを一時的にリダイレクトする
- エラー状態も返すopened()のバリアント
- もう1つの便利な例は、信号をブロックする操作です。
- この機能のもう1つの用途は、Decimalコンテキストです。
- これがdecimalモジュールの簡単なコンテキストマネージャーです
- 一般的な「オブジェクトを閉じる」コンテキストマネージャー
- 取得()呼び出しと解放()呼び出しを交換することにより、以前に取得したロックを一時的に解放するためのreleased()コンテキスト
- 過度のインデントを回避するために、提供されたコンテキストを左から右に自動的にネストする「ネストされた」コンテキストマネージャー