withの基本
ここでは、pythonのwithの基本的な使い方について記載する。
withは以下のように記述する。
with クラス as a:
処理
withはファイル入出力などの際によく用いられる。
withを利用する場合と利用しない場合で以下のような違いがある。
- withを利用しない場合
file.write('Hello') # ファイルに書き込む処理
file.close() # ファイルを閉じる処理
- withを利用する場合
file.write('Hello') # ファイルを開き、書き込み、閉じる一連の処理を行う
withを利用してファイルの入出力をしたら、ファイルを閉じる(close)する処理が自動的に実行される。
ファイルを閉じる処理を忘れると、メモリが解放されずリソースを逼迫して問題が生じることがある。
クラスを定義してwithで用いる
withは自身で定義したクラスで利用することもでき、with クラス名() as 変数名と記述する。
withで利用するクラスには、__enter__と__exit__の2つの特殊メソッドを定義する。
この時、withの後にインデントして記述した処理を実行する前に、指定したクラスの__enter__を呼び出しその返り値がasで指定した変数に格納される、処理終了後に、クラスの__exit__が呼ばれる
- withの実行例
def __init__(self, file_name): # コンストラクタ
self.file_name = file_name
def __enter__(self): # with開始前に呼び出される
self.file = open(self.file_name, 'w')
return self.file # 返り値がwithの変数に格納される
def __exit__(self):
self.file.close() # with終了に呼び出される
with FileWriter('test.txt') as file_writer:
file_writer.write('hello world')
# withでクラスを作成すると、まず__init__を実行、次に__enter__を実行、処理終了後に、__exit__を実行する
# file_writerには__enter__の返り値が格納される
withを利用する場面
withをどのように利用するかというと、連続した一連の処理を実行したい場合、
例えば
- ファイルの書き込み処理(ファイル開く→書き込む→ファイル閉じる)
- DBへのデータの書き込み処理(DBへコネクションを張る→書き込む→コネクションを閉じる)
などがある。
この場合、ファイルを閉じ忘れ、コネクションの閉じ忘れがあるとメモリが解放されずリソースを浪費することになる。
そのため、ファイル入出力、DBへの書き込み専用のクラスを別に定義して、
- ファイル入出力、DBへの書き込みはwithで利用
- ファイルを開く、DBへコネクションを張る処理を__enter__に定義
- ファイル書き込み、DBへの書き込みは、withの中の処理で記述
- ファイルを閉じる、コネクションを閉じる処理を__exit__に定義
などの使い方をする
このようにすると、ファイル入出力、DBへの書き込みが便利に行えるようになる
ちなみにファイルへの出力は一般的に以下のように記述する
【2020年版】: Python 3.8 データ構造、文法、アルゴリズム、オブジェクト指向、ライブラリ、完全マスター講座