【Python入門】with構文を使ってファイルを簡単に扱おう

今回は、with構文について解説します。with構文は主に外部のファイルを扱う場面で活躍する構文になります。この記事では

  • with構文とは
  • with構文の使い方

といった基本的な内容から

  • with構文が使えるクラスの作り方

など、より実践的な内容に関してもやさしく解説していきたいと思います。

本記事を読む前に、Pythonがどんなプログラミング言語なのかをおさらいしておきたい人は次の記事を参考にしてください。

→ Pythonとは?特徴やできること、活用例をわかりやすく簡単に解説

なお、その他のPythonの記事についてはこちらにまとめています。

目次

with構文とは

それではwith構文とはどのような働きをするのかについて、見ていきましょう。

with構文は、ファイルの読み込みが必要なコードでよく使われます。with構文を使うとファイルの読み込みで必要なclose処理を省略することが出来ます。

それではもう少しwith構文について知っておきましょう。

with構文を使うメリット

with構文は、開始と終了に必ずしなければいけない一連の作業がある場合に活躍します。

例えば

  • ファイルのオープンとクローズ
  • 通信の開始と終了
  • データベースへのアクセスのオープンとクローズ

などが一般的ですね。

with構文を使う一番のメリットは、開始時と終了時の定型処理を必ず実行してくれるということです。プログラマーがあえて意識しなくても、こういった手続きを行ってくれるのがwith構文になります。

with構文の使い方

では早速、with構文を使ってみましょう。

with構文の基本的な使い方

ファイルのオープンとクローズの作業を、with構文を使って簡略化してみましょう。

ファイル操作は、

  • ファイルのオープン
  • ファイルに対する処理
  • ファイルのクローズ

というのが決まった流れです。with構文を使わないコードだと、以下のようになります。

f = open("sample.txt", "r")
print(f.read())
f.close()

sample.txtというファイルをopenで開いた後、その内容を表示し、closeでファイルを閉じるという一連の流れを実行しました。

with構文を使うと以下のようになります。

with open("sample.txt", "r") as f:
    print(f.read())

コードの行数が減り、読みやすくなりましたね。withのすぐ隣に実行したい関数を明記します。そしてその関数が実行された後、インデント内に書いたコードが実行されます。

今回のサンプルコードのようなファイルの開閉作業だと、内容を表示した後、ファイルを自動的にクローズします。このように、with構文を使えば、明示的なクローズ処理が不要になるので安心ですね。

複数のwith構文を使う方法

複数のファイルを同時に開いて、処理を行いたい場合などはwith構文をネストする事が出来ます。以下のコードをご覧ください。

with open("sample1.txt", "r") as f1:
    with open("sample2.txt", "w") as f2:
        f2.write(f1.read())

こちらのコードでは、sample1.txtの内容をsample2.txtに書き込んでみました。

このように、同時進行的に何らかの作業を行いたい時などにはとても便利ですね。

with構文が使えるクラスを作ってみよう

ここからはステップアップのために、with構文を使ったクラスを作ってみましょう。

自分で実装した処理の中で、with構文を使うと便利なケースがあったとします。そのような場合は、with構文に対応したクラスを作る必要があります。

with構文が使えるクラスを作成するには、__enter__()メソッドと__exit__()メソッドの両方を定義しなければなりません。

先ほどのファイル開閉の例で説明すると、ファイルのopen処理が__enter__()メソッド、ファイルのclose処理が__exit__()メソッドの役割を担っています。

では、実際にwith文に対応したクラスを作ってみましょう。

class MySampleClass:
 
  def __enter__(self):
      print('START')
      return self
  
  def myfunc(self):
      print('Do something...')
  
  def __exit__(self, exception_type, exception_value, traceback):
    print('END')
 
with MySampleClass() as c:
  c.myfunc()

実行結果

START
Do something...
END

こちらのコードでは、MySampleClassというクラスを作成しました。

MySampleClass内には、__enter__メソッド、__exit__メソッドとmyfunc関数が定義されています。処理の開始時に__enter__メソッドが呼ばれ、STARTという文字列が出力されます。

そして次にmyfunc関数が実行され、Do something…という文字列が表示されます。処理の終了とともに、__exit__メソッドが呼ばれENDが表示されるという仕組みになっています。

まとめ

今回はPythonにおける基本的なwith文の使い方を解説しました。

抑えておきたい主なポイントは

  • 定型処理にwith文が便利!
  • 複数のwith文をネスト化もOK!
  • 自分でwith対応クラスも作成出来る

といったところですね。皆さんもぜひ、with文をマスターしてどんどんスマートなコードを書いて行ってくださいね。

この記事を書いた人

イタリア在住15年目の22歳です。イタリアの大学で情報科学&応用数学を学んでいます。主にJavaScriptやPythonについての記事を書いたりしています。

目次