[解決!Python]テキストファイルを読み込むには解決!Python

open関数やpathlib.Pathクラスを使ってファイルをオープンし、その内容を読み込む方法、with文と組み合わせる方法、テキストファイルを反復的に処理する基本パターンを紹介する。

» 2021年04月13日 05時00分 公開
[かわさきしんじDeep Insider編集部]
「解決!Python」のインデックス

連載目次

# ファイルをオープンして、1行ずつその内容を読み込んで処理する
with open('test.txt') as f:
    for line in f:
        line = line.rstrip()  # 読み込んだ行の末尾には改行文字があるので削除
        print(line)
# 出力結果(4行目に空行が表示されるときとされないときがあるのを除き、以下同じ)
#atmark IT
#
#deep insider

# テキストファイルをオープンして、その内容を全て読み込み、クローズする
f = open('test.txt'# f = open('test.txt', 'rt'):
s = f.read()  # ファイルの全内容が1つの文字列として返される
print(s)
f.close()

# with文と組み合わせると使い終わったとき(ブロック終了時)や
# 例外が発生したときにファイルが自動的にクローズされる
with open('test.txt') as f:
    s = f.read()

print(s)

# pathlibモジュールのPath.read_textメソッドを使う
from pathlib import Path

p = Path('test.txt'# s = Path('test.txt').read_text()
s = p.read_text()  # ファイルのオープン、読み込み、クローズをまとめて実行
print(s)

# 改行を区切り文字として文字列を分割し、リストに格納
sl = s.split('\n')
print(sl)  # ['atmark IT', '', 'deep insider', '']
for line in sl:
    print(line)

# readlineメソッドを使ってテキストファイルから1行ずつ内容を読み込む
with open('test.txt') as f:
    line = f.readline()
    while line:
        line = line.rstrip()
        print(line)
        line = f.readline()

# Python 3.8以降なら代入式を使ってシンプルに書ける
with open('test.txt') as f:
    while line := f.readline():
        line = line.rstrip()
        print(line)

# テキストファイルの内容をリストに読み込む
with open('test.txt') as f:
    sl = f.readlines()

print(sl)  # ['atmark IT\n', '\n', 'deep insider\n']

# readlinesメソッドを使って各行を順次処理するループを形成
with open('test.txt') as f:
    for line in f.readlines():
        line = line.rstrip()
        print(line)


テキストファイルを読み込む基本

 テキストファイルを読み込む基本的な流れは次のようになる。

  1. テキストファイルをオープンする(open関数)
  2. テキストファイルの内容を読み込み、利用する
  3. テキストファイルをクローズする(closeメソッド)

 open関数の構文を以下に示す。以下の構文で省略されているパラメーターについてはPythonのドキュメント「open()」を参照されたい。

open(file, mode='r')


 第1引数には、読み込みたいテキストファイルのファイル名を指定する。文字列でカレントディレクトリからの相対パスもしくは絶対パスでファイル名を指定するのが一般的だが、Pythonのpathlib.Pathオブジェクト(path-like object)を渡してもよい。

 第2引数には、ファイルをオープンするモードを指定する。省略した場合は「r」(読み込み)と「t」(テキストモード)が指定されたものとされる。そのため、テキストファイルを読み込み目的でオープンするのであれば、第2引数の指定は省略して、ファイル名を指定するだけでよい。

 以下に「open関数」→「ファイルからの読み込み(ファイルの利用)」→「ファイルのクローズ」という大まかな流れを示す。

f = open('test.txt'# 「f = open('test.txt', 'rt')」と同じ
# …… ファイルを利用 ……
f.close()

from pathlib import Path

filepath = Path('test.txt')
f = open(filepath)  # path-like objectを使用
# …… ファイルを利用 ……
f.close()


 ただし、ファイル操作時にはプログラム内外の現象を原因として例外が発生することもある。例外処理をきちんとしていないと、「open関数」→「ファイルからの読み込み」→「ファイルのクローズ」という流れの途中でプログラムが終了してしまう可能性もある。with文と組み合わせてファイルを扱うと、ブロック内の処理の終了時やブロック内で例外が発生したときには必ずファイルがクローズされるので、こちらを定型的に使うことをおすすめする。

with open('test.txt') as f:  # test.txtファイルをオープンして、変数fで扱う
    # …… ファイルを利用 ……
    pass

# with文が終われば、オープンしたファイルはクローズされる


 テキストファイルの処理とは、open関数でテキストファイルをオープンして、そのファイルを表すファイルオブジェクトを取得し、今度はそのファイルオブジェクトから何らかの形で各行のデータを取得し、それらを使って何らかの処理を行うということだ。

 実は、ファイルオブジェクトはそれ自体が反復可能オブジェクトとなっているので、ファイルオブジェクトをfor文に与えるだけで、各行を反復的に処理できる。以下ではファイルオブジェクト自体を利用した反復処理、ファイルオブジェクトが持つread/readline/readlinesメソッドを使った処理を見ていく。このときには、以下のような内容のテキストファイル「test.txt」を例に使う。

atmark IT

deep insider



テキストファイルから1行ずつ内容を読み込む

 ファイルオブジェクトを反復可能オブジェクトとしてfor文に与えて、各行を反復的に処理する典型的なコードを以下に示す。なお、以降はwith文と組み合わせたファイル読み込みのコードを示す。

with open('test.txt') as f:
    for line in f:
        line = line.rstrip()
        print(line)
# 出力結果:
#atmark IT
#
#deep insider


 この後に紹介するreadメソッドやreadlinesメソッドは、ファイルの内容を全てメモリに読み込むのに対して、この方法ではfor文のループが実行されるたびにファイルから1行だけがメモリへと読み込まれる。一度に全ての内容を読み込む必要がなければ、基本的にはテキストファイルを行ごとに処理するには、この方法を使うのがよいだろう。

 注意すべき点としては、読み込んだ行の末尾には改行文字が付加されている点だ。そのため、上のコードでは文字列のrstripメソッドを使って改行文字を削除している。この処理を省略した場合は次のようになる。各要素の末尾にある改行文字とprint関数が自動的に付加する改行文字により、以下のような結果になる。

with open('test.txt') as f:
    for line in f:
        print(line)
# 出力結果
#atmark IT
#
#
#
#deep insider
#


 テキストファイルをオープンした場合、それを表すファイルオブジェクトにはreadlineメソッドがある。これはファイルから1行だけを読み込むメソッドだ。これを使うと、上のコードは次のようにも記述できる。

with open('test.txt') as f:
    line = f.readline()  # readlineメソッドで上と同じことを行う
    while line:
        line = line.rstrip()
        print(line)
        line = f.readline()

with open('test.txt') as f:
    while line := f.readline():  # 代入式でシンプルに(Python 3.8以降)
        line = line.rstrip()
        print(line)


 だが、こうした記述をするのであれば、先ほどのようにファイルオブジェクトを反復オブジェクトとして使う方がスッキリとするはずだ。なお、要素の末尾に改行文字が付加されるのが面倒に感じられるかもしれないが、テキストファイル中の空行には改行文字が付加される一方で、ファイル末尾以降を読み込もうとしたときには空文字列が返される。こうすることで、ファイル末尾までを読み込んだかそうでないかを判断できることは覚えておこう(上のコードを、よりシンプルにしようとして「f.readline().rstrip()」のようにすると、空行と空文字列の区別が付かなくなる)。

テキストファイルをオープンして、その内容を全て読み込み、クローズする

 テキストファイルをオープンして、その内容を全て読み込み、クローズするときにはreadメソッドが使える。このメソッドは、テキストファイルの内容を全て読み込んで、単一の文字列として返送する。以下に例を示す。

with open('test.txt') as f:
    s = f.read()

print(s)


 これにより、テキストファイルの内容全体が変数sに代入される(改行文字を含む)。対話環境(REPLやJupyter Notebookなど)で変数sの値を「s」のようにして評価すると、その値が見られる。

# 'atmark IT\n\ndeep insider\n'


 このように文字列全体の末尾にも改行文字があるので、「print(s)」のようにすると、最後に空行が表示される点には注意してほしい。

 同様な処理は、pathlibモジュールのPathクラスのインスタンスメソッドread_textを使っても行える。ファイルのオープンやクローズを気にすることなく、テキストファイルの内容を読み込めるので、こちらの方法も覚えておくとよいかもしれない。

from pathlib import Path

p = Path('test.txt'# s = Path('test.txt').read_text()
s = p.read_text()  # ファイルのオープン、読み込み、クローズをまとめて実行
print(s)


 どちらの方法にしても、単一の文字列としてファイルの内容が返送されるが、その内容を行ごとに扱いたいのであれば、改行文字を区切り文字として文字列を分割する。

sl = s.split('\n')
print(sl)  # ['atmark IT', '', 'deep insider', '']
for line in sl:
    print(line)


 readメソッドで読み込んだ末尾に改行文字が付加されている場合、splitメソッドで分割した結果(リスト)の最終要素が空文字列となる点には注意しよう。ただし、この手間を考えると最初に紹介した方法が簡潔だろう。各行を反復的に処理したいのではなく、ファイル全体の内容をさらに何かの関数やメソッドに渡して、処理したいのであれば、このメソッドを使うのがよい。

テキストファイルの内容をリストに読み込む

 上のreadメソッドの例で見たような、テキストファイル全体を読み込んでから、各行を分割して、それらを要素とするリストを作成したいのであれば、readlinesメソッドを使う。readlinesメソッドはまさにそうした処理をしてくれる。

 以下に例を示す。

with open('test.txt') as f:
    sl = f.readlines()  # 「sl = list(f)」でもよい(説明は省略)

print(sl)  # ['atmark IT\n', '\n', 'deep insider\n']


 readメソッドで得たファイル全体の内容をsplitメソッドで分割したときには、改行文字が削除されていたが、こちらでは各要素の末尾に改行がある点には注意しよう。必要があれば、文字列のrstripメソッドを呼び出すなどして、改行文字を削除する。

 readlinesメソッドの戻り値は各行を要素とするリストなので以下のように反復処理を行うことも可能だ。

with open('test.txt') as f:
    for line in f.readlines():
        line = line.rstrip()
        print(line)


 ただし、これについても基本的にはファイルオブジェクトに対して反復処理を行うことで、同じことを実現できるので、あまり使う場面はないかもしれない。

「解決!Python」のインデックス

解決!Python

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

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

メールマガジン登録

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