はじめに
ファイルを読み込むモジュールは複数あり、違いがあいまいなまま使用していたので、
正しく理解しておこうと思い立ち書きました。
環境
- OS :CentOS Linux release 7.6.1810 (Core)
- Python:Python 3.7.5
3つのモジュール
Pythonでファイルを読み込む時によく使用されるモジュールは、下記の3つです。
各モジュールでファイルを読み込んで、どのように格納されるのか比較します。
モジュール名 | 説明 |
---|---|
read() | ファイルを全て読み込みstr型変数に格納する。 |
readline() | ファイルを1行読み込みstr型変数に格納する。 |
readlines() | ファイルを全て読み込みlist型変数に格納する。 |
※正しくは、「ストリームを読み込み」です。
この記事ではファイル名を指定して、ファイルに限定しているので
「ファイルを読み込み」と記述しています。
テスト用のテキストファイル
下記ファイルを読み込み用として作成します。
aaa
bbb
ccc
ddd
eee
テストコード
下記のコードで確認を行います。
#!/usr/bin/env python
FILENAME="file.txt"
# read() test
def read_file():
fd = open(FILENAME, mode='r')
data = fd.read()
fd.close()
print(type(data))
print(data)
# readline() test
def readline_file():
fd = open(FILENAME, mode='r')
data = fd.readline()
fd.close()
print(type(data))
print(data)
# readlines() test
def readlines_file():
fd = open(FILENAME, mode='r')
data = fd.readlines()
fd.close()
print(type(data))
print(data)
print("=== read() test ===")
read_file()
print("=== readline() test ===")
readline_file()
print("=== readlines() test ===")
readlines_file()
実行結果
実行して、結果を表示します。
$ ./readtest.py
=== read() test ===
<class 'str'>
aaa
bbb
ccc
ddd
eee
=== readline() test ===
<class 'str'>
aaa
=== readlines() test ===
<class 'list'>
['aaa\n', 'bbb\n', 'ccc\n', 'ddd\n', 'eee']
各モジュールの結果を見ていきます。
read()の実行結果
ファイルの内容が、改行コード込みでstr型変数に入っています。
=== read() test ===
<class 'str'>
aaa
bbb
ccc
ddd
eee
注意)
file.txt で、eeeの後に改行がある場合、出力は下記のように空行が含まれます。
eee
<-- 空行がある
readline()の実行結果
1行目だけがstr型変数に入っています。
ファイルの内容を全て読み込む場合は、繰り返し処理が必要です。
=== readline() test ===
<class 'str'>
aaa
注意)
file.txt で、aaaの後に改行があるため、出力には空行が含まれています。
繰り返し処理を行う場合は、以下のように書けます。
fd = open(filename, mode='r')
for line in fd:
print(line, end="")
fd.close()
readlines()の実行結果
1行1要素とした、list型変数に入っています。
=== readlines() test ===
<class 'list'>
['aaa\n', 'bbb\n', 'ccc\n', 'ddd\n', 'eee']
list型なので、for文で1行づつ取り出せます。
for line in data:
print(line)
注意)
file.txt で、eeeの後に改行がある場合、出力は下記のように改行が含まれます。
['aaa\n', 'bbb\n', 'ccc\n', 'ddd\n', 'eee\n']
最後に
個人的にはreadlines()でlist型にした方が扱いやすくて好みです。
しかし、読み込むファイルが大きいサイズだと一度に読み込むより、
readline() で行ごとに処理したほうが良い場面も出てくるでしょう。
使うモジュールは、用途で変わるので正しい選択をするための手掛かりになれば幸いです。