Python の「with」ステートメントは何に使用されますか?
質問
Pythonのwithステートメントを理解しようとしています。どこを見ても、ファイルを開いたり閉じたりすることが書かれており、try-finally ブロックを置き換えることを目的としています。誰か他の例も投稿してもらえませんか。私はフラスコを試しているところですが、そこには with ステートメントがたくさんあります。誰かにそれについて明確に説明してもらうよう必ず依頼してください。
解決
ここを非常に素晴らしい説明があります。基本的には、ステートメントに関連したオブジェクト上の2つの特別なメソッドを呼び出します。 __enter__と__exit__方法。メソッドが返す「と」文に関連付けられている変数を入力します。 __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
ステートメントが大幅に役立つ他の場所の関数とクラスデコレータの主要な利点と同様である:それは、コードの行の任意の数によって分離することができる「ツーピース」コード、(デコレータの関数定義を取り現在のケースでは、try
ブロック)とプログラマは単に、彼らが何をしようとして前を宣言し、「ワンピース」のコードに変わることを。
は、短い例については、これは大きなゲインのようには見えませんが、コードをレビューするとき、それは実際には大きな違いになります。私はコードの一部でlock.acquire()
を見ると、私は下にスクロールして、対応するlock.release()
をチェックする必要があります。私はwith lock:
を参照すると、にもかかわらず、そのようなチェックは必要ありません - 私は、ロックが正しく解放されることをすぐに見ることができます。
使用例は 12 個あります with
で PEP343, ファイルを開く例を含む:
- 開始時に取得されたロックを確実にするためのテンプレート ブロックは、ブロックが残されたときに解放されます
- ファイルを確実に閉じるファイルを開くためのテンプレート ブロックが残っているとき
- データベーストランザクションをコミットまたはロールバックするためのテンプレート
- 例 1 ジェネレーターを使用せずに書き換えた例
- 標準出力を一時的にリダイレクトする
- エラー条件も返すopened()のバリアント
- 別の有用な例は、信号をブロックする操作です
- この機能のもう 1 つの用途は、Decimal コンテキストです。
- これは 10 進数モジュールの単純なコンテキスト マネージャーです。
- 汎用の「オブジェクトを閉じる」コンテキスト マネージャー
- acquire() と release() の呼び出しを交換することで、以前に取得したロックを一時的に解放するための release() コンテキスト
- 「ネストされた」コンテキストマネージャで、 過度に避けるために左から右にコンテキストを提供しました 圧入