Python | コンテキストマネジャーとwithの使い方

公開日:2021/6/9

Pythonにて何らかの処理が完了した後,メモリの開放やファイル同士の連結を終了させる必要がある.解放や終了をしない場合,余計なリソースが割かれたり,システム遅延やクラッシュの原因となる.このような時,リソースを開放しなくとも,コンテキストマネジャーとwithを利用した構文はタスクを実行することができる.以下に「コンテキストマネジャーとwithを利用した基本構文」,「コンテキストマネジャーとwithを利用した書き出し」の2構成でコンテキストマネジャーとwithの使い方を記す.

◆実施環境

Python 3.8.8

■準備(当準備は2で利用)

現在以下URL(カレントディレクトリ)で開発しているので,”210517_python development”フォルダの直下に”test”のいう名のフォルダを作成した.

“PS C:\Users\shiro\Desktop\210517_python development>”

テキストファイルを作成し,書き出すためのファイルパスは以下になる.(準備段階ではテキストファイルは作成されていない)

“test/writing.txt”

  1. コンテキストマネジャーとwithを利用した基本構文

クラスを定義した後,"__init__"メソッド,"__enter__"メソッド,"__exit__"メソッドを定義する.その後,"with as"を利用する.

# 1の処理
class ContextManager:

  def __init__(self):
    print('init呼び出し') # 1番目処理

  def __enter__(self):
    print('enter呼び出し') # 2番目処理

  def __exit__(self, exc_type, exc_val, exc_traceback):
    print('exit呼び出し') # 4番目処理

with ContextManager() as t:
  print('with statement内') # 3番目処理

# 2の処理
class ContextManager:

  def __init__(self,msg):
    print('init呼び出し') # 1番目処理
    self.msg = msg

  def __enter__(self):
    print('enter呼び出し') # 2番目処理
    print(self.msg)
  
  def __exit__(self, exc_type, exc_val, exc_traceback):
    print('exit呼び出し') # 4番目処理

with ContextManager('Test') as t: # 3番目処理
  print('with statement内')

■実行結果

# 1の結果
init呼び出し
enter呼び出し
with statement内
exit呼び出し

# 2の結果
init呼び出し
enter呼び出し
Test
with statement内
exit呼び出し
  1. コンテキストマネジャーとwithを利用した書き出し
# 1の処理
class ContextManager:
  
  def __init__(self,docname):
    print('init呼び出し')
    self.__docname = docname

  def __enter__(self):
    print('enter呼び出し')
    self.__doc = open(self.__docname,mode='w',encoding='utf-8')
    return self

  def greeting(self,content):
    self.__doc.write(content)

  def __exit__(self, exc_type, exc_val, exc_traceback):
    print('exit呼び出し')
    self.__doc.close()

with ContextManager('test/writing.txt') as t: # 準備したファイルパスを利用する
  print('with statement内')
  t.greeting('Hello World')

■実行結果

# 1の結果
init呼び出し
enter呼び出し
with statement内
exit呼び出し

上記+以下を出力(テキストファイルが作成され,以下が記述)

Hello World

以上