[Pythonクイズ]ファイルの内容を読み込むコード、もっとカンタンに書けますよ?Pythonステップアップクイズ

open関数でファイルをオープンして、readメソッドでファイルの内容を読み込んで、最後にcloseメソッドでファイルをクローズする。それがふつ~かもしれませんが、もっとカンタンに書く方法がありますよ?

» 2025年02月18日 05時00分 公開
[かわさきしんじDeep Insider編集部]
「Pythonステップアップクイズ」のインデックス

連載目次

ファイルのオープン、読み込み、クローズなんてもっとカンタンに書けるよ! ファイルのオープン、読み込み、クローズなんてもっとカンタンに書けるよ!

【問題】

 以下は「example.txt」という名前のファイルをopen関数で開いて、その内容を変数contentに読み込むPythonコードである。しかし、このコードはより簡潔に記述できる。どんな書き方が考えられるだろうか。

file = open('example.txt', 'r')
content = file.read()
file.close()

「example.txt」という名前のファイルを開いて、その内容を変数contentに読み込む

かわさき

 どうもどうも。HPかわさきです。今回も正解は1つじゃないパターンです。多くの人が「ふつ~、コレでしょ!」という書き方はアレでしょう。でも、筆者はそれとは違うやり方が好みです。特にサンプルコードの中でファイルの内容を見せたいようなときには、違うやり方の方が簡単に書けますからね。さて、筆者の好みのコードとはどんな書き方でしょう。


【答え】

 正解のコード例を以下に示します。

# その1
with open('example.txt', 'r') as file:
    content = file.read()

# その2
from pathlib import Path

content = Path('example.txt').read_text()

正解のコード例。with文を使うものとpathlibモジュールを使うものを例とした

 その1としたのはwith文を使う例です。多くの方はこちらを思い浮かべると思います。with文を使うことで、ファイルのクローズが必ず行われるようになることから問題文のようなコードではなく、こちらを使うことがPythonでは一般的ともいえますね。

 その2のコードはpathlibモジュールのPath.read_textメソッドを使う例です。ファイルのオープン、内容の読み込み、ファイルのクローズを1つのメソッドで行えるのでより簡潔ともいえます。

正解はきっとこれらだけじゃない…… 正解はきっとこれらだけじゃない……

【解説】

 問題文のコードは次のようなものでした。

file = open('example.txt', 'r')
content = file.read()
file.close()

file.closeメソッドが確実に実行されるか分からない

 このコードには次のような考慮点があります。

  • closeメソッドを自分で呼び出している
  • readメソッドでファイルの内容を読み込む際に例外が発生するとcloseメソッドが呼び出されなくなってしまう

 もちろん、上のコードではcloseメソッド呼び出しが書かれているので、readメソッドで例外が発生しなければ、ファイルは確実にクローズされるでしょう。しかし、人という生き物は物忘れをするものです。ファイルのオープンからクローズまでにたくさんのコードを書かなければならないときには、closeメソッドを書き忘れるなんてことはよくあるかもしれません。

 closeメソッドの呼び出しを忘れると、そのファイルがずっとオープンされっ放しになって、無駄なリソースをプログラムの実行中に消費し続けることになります。ファイルがオープンされ続けているので、他のプログラムがそのファイルを使いたいのに使えないといった状況が発生するかもしれません。

 closeメソッド呼び出しを書き忘れなくても、それまでの間に何らかの原因で例外が発生すれば(問題文ならreadメソッドで例外が発生すれば)、closeメソッドが実行されないまま、上位のフレームに制御が移り、プログラムが終了してしまうかもしれません。

 書き込みモードでファイルをオープンしていたとすると、writeメソッドを呼び出してファイルへ何かを書き込んだつもりでも、closeメソッドが呼ばれるまではバッファリングにより書き込みが遅延されたままとなり、ファイルへの書き込みが行われない可能性もあるでしょう。

 冷蔵庫の開け閉めと同じで、使い終わったファイルは確実かつ迅速にクローズすることが重要です。それを可能にしてくれるのがwith文です。

 with文はPythonのコンテキストマネジャーと呼ばれる機構を使って、with文のブロックを実行する前に何らかのコンテキストを設定し、ブロックの実行後にそのコンテキストの後処理を確実に行えるようにします。

with open('example.txt', 'r') as file:  # コンテキスト(ファイル)の用意
    content = file.read()  # コンテキストの利用
                           # ブロックが終わったところでファイルがクローズされる

with文を使うとファイルが自動的にクローズされる

 この例ではコンテキストとはファイルのことだと考えてよいでしょう。上の「with open('example.txt', 'r') as file:」という部分で、with文のブロックである「content = file.read()」を実行する前にファイルをオープンして、ブロックの内部でそれを利用できるようにし、ブロックの実行後にはファイルをクローズしてくれるということです。

 with文のブロックを実行中に例外が発生した場合でも、コンテキストの後処理は行われるので、ファイルのクローズ忘れを心配する必要がなくなります。例えば、以下のコードを実行すると、ファイルがクローズされたかどうかを示すfile.closed属性はTrueになります。

with open('example.txt', 'r') as file:
    content = file.read()
    raise Exception('Error')

print(file.closed)  # True

例外が途中で発生してもファイルはクローズされる

 そして、今見てきたような処理をさらに抽象化したのが、pathlibモジュールのPath.read_textメソッドです。ファイルのオープンや読み込み、クローズといった処理を1つのメソッドにまとめたものと考えてよいでしょう。

from pathlib import Path

content = Path('example.txt').read_text()

ファイルのオープン、読み込み、クローズまでがread_textメソッドで行われる

 実はread_textメソッドの内部ではwith文を使って、ファイルをオープンし、その内容をreadメソッドで読み出して、ファイルをクローズし、その内容を返送するようになっています。


かわさき

 というわけで、筆者が好んで使っている違うやり方は「その2」のPath.read_textメソッドを使うものでした。皆さんもガンガン使ってくださいね。

 また、カンタンではなく、単に書き換えるというだけであれば、try-finally文を使ってファイルのクローズが確実に行われるようにするなどの方法が考えられます。が、多くの場合はwith文を使うか、pathlibモジュールを使うかになるんじゃないかなぁ。


 では、これら2つの方法をどのように使い分ければよいかというと、次のような指針が考えられるでしょう。

  • read_textメソッドがオススメ:小サイズのファイルの内容をまとめて読み込みたい
  • with文がオススメ:大サイズのファイルの内容を逐次的に読み込んで処理したい

 read_textメソッドはファイルの内容をまとめて読み込むので、そのサイズが大きいときにはメモリの消費量も増えてしまいます。サイズが大きなファイルから、ある程度のサイズごとに読み込みを行い、それに対して何らかの処理を加えるといったループ処理をしたいのであれば、with文を使うのがよいでしょう。


かわさき

 with文については「Python入門」の「ファイル操作と例外処理」でも取り上げているので、興味のある方はそちらもぜひご覧ください。

 なお、今回の問題を考えたのはDeep Insider編集部の一色さんでした。皆さんも「こんな問題あるよ!」ってのがあったら、HPかわさきまでお知らせくださいね。


「Pythonステップアップクイズ」のインデックス

Pythonステップアップクイズ

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

Deep Insider 記事ランキング

本日月間

注目のテーマ

4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。