Pythonでのコンテキスト管理

0 x00

ステートメントブロックを実行するときは、いくつかの準備アクションが必要であり、実行が完了した後、いくつかの終了アクションを実行する必要があります。例:読み取りと書き込みの後にファイルを閉じる必要があり、データベースの読み取りと書き込みの後に接続を閉じる必要があり、リソースがロックおよびロック解除されます。この場合、Pythonはコンテキスト管理の概念を提供します。これは、コードブロックの実行前に準備アクションを処理し、コンテキストマネージャーを介して実行後に終了アクションを処理するために使用できます。

withステートメント#を使用します

まず、コンテキストマネージャーを使用できない状況を見てください

f =open("log.txt","w")try:
 f.write("hello")finally:
 f.close()

コンテキストマネージャーを使用する

withopen("log.txt","w")as f:
 f.write("hello")

ステートメントを閉じると、Pythonは自動的に f.close()メソッドを呼び出します。

Withステートメントは内部で私たちに何をしますか?

  1. withの後に open(" log.txt "、" w ")ステートメントによって返されるオブジェクトの __enter__メソッドが呼び出され、 __enter__の戻り値が asの後に変数に割り当てられます。

  2. withが実行されると、フロントエンドリターンオブジェクトの __exit__メソッドが呼び出されます。

テストするクラスを書いてみましょう。

classContextTest:
 def __enter__(self):print("エンターエンター!")return"Foo"

 def __exit__(self,*args,**kwargs):print("出口に入る!")

def get_sample():returnContextTest()withget_sample()as sample:print(f"Sample: {sample}")

動作結果:

エンターエンター!
Sample: Foo
出口に入る!

自分でコンテキストマネージャーを実装する#

** enter および exit ** ##によって達成されます

上記のwithステートメントの原則に従って、クラスを使用して、ファイルを開くためのwithステートメントをサポートするクラスを実装します。

classFile:
 def __init__(self, file_name: str, method: str):
  self.file_obj =open(file_name, method)

 def __enter__(self):return self.file_obj

 def __exit__(self, exc_type, exc_val, exc_tb):
  self.file_obj.close()print(f"type: {exc_type}")print(f"value: {exc_val}")print(f"traceback: {exc_tb}")withFile('demo.txt',"w")as f:
 f.useless_func()

ここでも例外処理を実装しました。例外処理に関しては、withステートメントは次のように実行されます。

  1. 異常な exc_type exc_valexc_tb __exit__メソッドに渡します
  2. __exit__メソッドが例外を処理できるようにします
  3. __exit__がTrueを返す場合、例外は無視されます。
  4. __exit__がTrue以外を返す場合、この例外はwithステートメントによってスローされます。

出力結果は次のとおりです。

type:<class'AttributeError'>
value:'_io.TextIOWrapper' object has no attribute 'useless_func'
traceback:<traceback object at 0x000001D259D82908>Traceback(most recent call last):...
AttributeError:'_io.TextIOWrapper' object has no attribute 'useless_func'

contexlibモジュールデコレータとジェネレータによって実装されます##

from contextlib import contextmanager

@ contextmanager
def my_open(filename, mode):
 file_obj =open(filename, mode)try:yield file_obj.readlines()
 except Exception as e:
  raise e

 finally:
  file_obj.close()if __name__ =='__main__':withmy_open(r'demo.txt','r')as f:for line in f:print(line)

降伏前のコードは __enter__メソッドで実行され、降伏後のコードは __exit__メソッドで実行されます。基本的に、これは __enter__メソッドと __exit__メソッドです。 @ contextmanagerのデコレータはジェネレータを受け入れるため、 yieldステートメントを使用して with ... as varの変数を出力すると、withステートメントは正常に機能します。

contextlibモジュール#

ファイルやデータベースなどの開閉を引き継ぐだけでなく、 @ contextmanagerの機能を使用して、いくつかの優れた機能を実行することもできます。特定のコードの実行の前後に特定のコードを自動的に実行する場合は、 @ contextmanagerを使用して実現することもできます。

@ contextmanager
def tag(name):print("<%s>"% name)yieldprint("</%s>"% name)withtag("h1"):print("hello")print("world")

# 出力
< h1>
hello
world
< /h1>

@ closing

オブジェクトがコンテキストを実装していない場合、 withステートメントで使用することはできません。現時点では、 closeingを使用してオブジェクトをコンテキストオブジェクトに変換できます。たとえば、 withステートメントでurlopen()を使用します

from contextlib import closing
from urllib.request import urlopen

withclosing(urlopen('https://www.python.org'))as page:for line in page:print(line)

この魔法の「クロージング」のソースコードを見てみましょう

classclosing(AbstractContextManager):"""Context to automatically close something at the end of a block.

 Code like this:withclosing(<module>.open(<arguments>))as f:<block>

 is equivalent to this:

  f =<module>.open(<arguments>)try:<block>finally:
   f.close()"""
 def __init__(self, thing):
  self.thing = thing
 def __enter__(self):return self.thing
 def __exit__(self,*exc_info):
  self.thing.close()

上記のクラスメソッドで行ったのと同じです〜

参照#

[ Liao XuefengのPythonチュートリアル-contextlib](https://www.liaoxuefeng.com/wiki/1016959663602400/1115615597164000)[ステートメントコンテキスト管理を使用したPythonの2つの実装方法](https://www.cnblogs.com/tkqasn/p/6003959.html)[Pythonでのwithの使用と原則](https://blog.csdn.net/u012609509/article/details/72911564)

Recommended Posts

Pythonでのコンテキスト管理
pythonの関数
03.Pythonエントリの演算子
12.Python3でのネットワークプログラミング
pythonでステートメントを印刷する
Pythonでの同時リクエスト
Ubuntuにpythonをインストールする
pythonの算術演算子
pythonでguiを書く
PythonでのMongoDBの使用
Pythonクローラーgerapyクローラー管理
PythonのStr文字列
Pythonでの計算ジオメトリ
Pythonでの同時リクエスト(パート2)
Pythonのタプルの添え字
Pythonランタイム例外管理ソリューション
Pythonは駐車場管理システムを実現
Python3.9の注目すべき更新ポイント
Pythonは車の管理システムを実装しています
Pythonアプリケーションを3分でコンテナ化
pythonのイントロスペクションとは何ですか
pythonのオブジェクト指向とは何ですか
Pythonのジェネレーターとイテレーター
Pythonで文字列について話す
pythonでのwheelの使用法
Pythonの対数法の要約
Python開発でのパンダの使用
pythonでnohupコマンド命令を使用する
pythonによる学生管理システムの実装
pythonのリスト内包表記とは何ですか
Pythonは名刺管理システムを実現
PythonでNumpyを使い始める
詳細な並べ替えアルゴリズム(Pythonで実装)
pythonコードでラップする方法
pythonの一般的なエラーと解決策
Python開発でのnumpyの使用
Python3は名刺管理システムを実現
pythonのdefは何をしますか
Pythonで括弧を省略する方法
Pythonでの辞書の詳細な使用法
pythonでのosパッケージの使用
Pythonでのガベージコレクションについて学ぶ
pythonでクラスを書く方法
pythonで数値をフィルタリングする方法
Pythonの数字は何ですか?
PythonでExcelを読む方法
Pythonにはいくつかのキーワードがあります
python学生管理システムの実装
Pythonのすべてがオブジェクトです
pythonでエラーを表示する方法
npはpythonで何をしますか
pythonでreturnを書く方法
Pythonのモジュールについて話す
Pythonで変数を理解する方法
pythonで変数をクリアする方法
pythonでのタプルの使用法
PythonでSQLiteを使用する方法
pythonmysqlのパラメータ化の説明
pythonでのrbの意味を理解する
python言語のアルゴリズムはありますか
およびおよびまたはPythonでの使用方法