私たちの多くは、Python コードで次のコード スニペットを何度も見たことがあります:
with open('Hi.text', 'w') as f: f.write("Hello, there")
しかし、私たちの中には、何が必要なのか、なぜ必要なのかがわからない人もいます。ここでそれを使用します。この本を読めば、解決できるほぼすべての問題がわかります。はじめましょう!
まず、with キーワードを使用せずに何をする必要があるかを考えてみましょう。この場合、最初にファイルを開いて書き込みを試みる必要があります。成功か失敗かに関係なく、最後に閉じた方がよいので、コードは次のようになります。
f = open('Hi.text', 'w') try: f.write('Hello, there') finally: f.close()
それでは、 with キーワードは何に使われるのでしょうか?これは、try..finally コードを 1 つの with... ステートメントに短縮するのに役立ちます。 with文の使い方はこんな感じです。
それで、それは正確には何ですか?実際、with ステートメント自体は Python では特別なものではなく、Python のコンテキスト マネージャーの単なる機能です。 Python の公式ドキュメントから引用されているコンテキスト マネージャーは、必要なときに正確にリソースを割り当てたり解放したりできるようにする方法です。簡単に言うと、あるリソースに対して何かを行うときにコード スニペットを短くします。つまり、使用方法を定義できるということです。 with ステートメントを自分で作成してください。
どうやってこれを行うのでしょうか?それは簡単です。2 つのマジック関数を実装する必要があるだけです。1 つは __enter__ と呼ばれ、もう 1 つは __exit__ と呼ばれます。 1 つ目の方法は、以下に示すように、これら 2 つの関数を実装するクラスを作成することです。
class My_file: def __init__(self, fname): self.fname = fname def __enter__(self): self.file = open(self.fname, 'w') return self.file def __exit__(self, exc_type, exc_val, exc_trace_back): if self.file: self.file.close()
ここでは、2 つのマジック関数を実装する通常の Python クラスを作成しました。これら 2 つの関数のシグネチャに注意してください。 __enter__ は self のみを受け入れますが、 __exit__ はさらに多くの引数を受け入れます。例の 3 つは標準形式です。
with My_file('hello.txt') as f: f.write('hello, world!')
ここの with ステートメントは、最初に __init__ を呼び出して新しいオブジェクトを構築し、次に __enter__ メソッドを呼び出します。最後に、コード ブロックの前に __exit__ メソッドをトリガーします。完成されました。したがって、上記のコードの大まかな同等物は次のとおりです。
myfile = My_file('hello.txt') f = myfile.__enter__() f.write('hello, world!') myfile.__exit(...)
コンテキスト マネージャーを実装する 2 番目の方法は、次のようにデコレータを使用することです。
上記の紹介に従って、デコレータ コンテキスト マネージャーを作成しましょう。
from contextlib import contextmanager @contextmanager def my_file_open(fname): try: f = open(fname, 'w') yield f finally: print('Closing file') f.close() with file_open('hi.txt') as f: f.write('hello world')
上記では、with ステートメントとコンテキスト マネージャーの基本をほぼすべてカバーしていますが、さらに詳しく知りたい場合は、続けてください...!
contextlib には、使用できる便利なツールがいくつかあります。最初のものは閉じています。閉じると、基本的にコードのブロックが、終了する前に実装する別の関数でラップされます。
@contextmanager def closing(f): try: f.write("Finish writing") finally: f.close() with closing(open("hi.text")): f.write("hello world")
たとえば、上記のコードでは、close(your_way_of_getting_resource) を直接呼び出すことができ、以下に記述するコード ブロックが完了する前 (f.write("hello world")) に、上で定義した try ..finally ブロックを実行します。
もう 1 つは抑制ツールを使用することです。多くの場合、リソースを取得しようとすると、ファイルを開くときに FileNotFoundException などのエラーが発生する可能性が高いことがわかっています。場合によっては、プログラムが正常に実行し続けることができるように、エラーを検出したり、エラーを抑制したりする必要があります。抑制は、警告を抑制できる 1 つの方法です。必要なのは、抑制したい例外を特定し、suppress(your_choice_of_Exception) を記述することだけです。そうすれば、Python がそこから処理します。
他の場合には、with ブロックに入るときに特定のアクションのみを実行したい場合があります。この場合、nullcontext が便利です。 nullcontext は __enter__ 関数で定義したものを返すだけで、他には何も行いません。リソースにアクセスするために Python で非同期操作を処理している場合、この状況を処理するためのユーティリティが aclosure です。
この記事では、with ステートメントの基本的な概念と使用法、およびその基礎となる動作原理を紹介します。他にも興味深いものがたくさんあります。Python の contextlib ドキュメントをチェックしてください。最後に、いつものように楽しく学習し、楽しくコーディングできることをお祈りしています。
以上がPython の with キーワードをわかりやすく理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。