Pythonでテキストファイルを読み書きする

この記事では、Pythonでテキストファイルを扱う場合に必要な情報をお伝えします。

主に、open・close・read・writeの説明をします。

ファイルをopen・closeする

openの仕様書です。

openの基本的な使い方です。

# ファイル名を決める。
filename = 'test_sjis.txt'

# ファイルの置き場所を決める。コードと同じディレクトリとする。
file_path = os.path.join(os.getcwd(), filename)

# ファイルをopenする。
f = open(file_path, mode='w', encoding='shift_jis')

# ファイルに書き込む。
f.write('あいうえお')

# ファイルをcloseする。
f.close()

modeパラメータで用途を決める

modeの代表的な設定値です。

文字意味
‘r’読み込み用に開く。
‘w’書き込み用に開く。新規作成上書きとなる。
‘x’新規作成で書き込み用に開く。ファイルが存在する場合は失敗する。
‘a’追記用に開く。
‘b’バイナリモード。

新規作成か上書きとなるmode=’w’で使うのが通常と思います。
追記する場合はmode=’a’にします。

すでに存在するファイルをmode=’x’でopenするとFileExistsErrorになります。

FileExistsError: [Errno 17] File exists

encodingパラメータで文字コードを決める

encodingの設定値のバリエーションは仕様書に詳しく書かれています。

日本だと、encoding=’utf_8‘、’shift_jis‘、’cp932‘、’ascii‘あたりかと思います。
これらでNGなら仕様書に他の設定値が書かれているので、試してみてください。

Shift_JISで保存したファイルをUTF-8で読もうとするとUnicodeDecodeErrorとなります。

UnicodeDecodeError: 'utf-8' codec can't decode byte

上で作成したtest_sjis.txtを使ってUnicodeDecodeErrorになるコードを書くとこうなります。
encoding=’shift_jis’なら読めるが、’utf_8’だとエラーになります。

# ファイル名を決める。
filename = 'test_sjis.txt'

# ファイルパスを決める。
file_path = os.path.join(os.getcwd(), filename)

# ファイルをopenする。
f = open(file_path, mode='r', encoding='shift_jis')

# ファイルを読み込む。
print(f.read())

# あいうえお

# ファイルをcloseする。
f.close()

# ファイルをopenする。
f = open(file_path, mode='r', encoding='utf_8')

# ファイルを読み込む。
print(f.read())

# UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte

withキーワードでファイルオブジェクトを扱う

withキーワードでファイルオブジェクトを扱うことを推奨されています。
理由は、処理中に例外が発生しても必ず最後にファイルを閉じてくれるからです。

# ファイル名を決める。
filename = 'test_sjis.txt'

# ファイルパスを決める。
file_path = os.path.join(os.getcwd(), filename)

# ファイルオブジェクトをwithで扱う。
with open(file_path, encoding='shift_jis') as f:
    print(f.read())

    # あいうえお

# ファイルが閉じられているか確認する。
print(f.closed)

# True

テキストを書き込む

writeで文字列を書く

writeは文字列をファイルに書き込み、書き込まれた文字数を返す。

# ファイル名を決める。
filename = 'test_sjis.txt'

# ファイルパスを決める。
file_path = os.path.join(os.getcwd(), filename)

# 書き込む文字列の作成。
text = 'hello\n'

# ファイルオブジェクトをwithで扱う。
with open(file_path, mode='w', encoding='shift_jis') as f:
    num = f.write(text)
    print(num)

    # 6
    # helloと改行文字で6文字が返る。

writelinesで一連の文字列を書く

writelinesは一連の文字列を書き込みます。改行文字は入れないと勝手に挿入されません。

# ファイル名を決める。
filename = 'test_sjis.txt'

# ファイルパスを決める。
file_path = os.path.join(os.getcwd(), filename)

# 書き込む一連の文字列の作成。
texts = [
    'hello',
    'new',
    'world',
    ]

# ファイルオブジェクトをwithで扱う。
with open(file_path, mode='w', encoding='shift_jis') as f:
    f.writelines(texts)

# test_sjis.txtには
# hellonewworld
# と出力される。改行文字は付かない。

テキストを読み込む

readで読み込む

readは、ファイル内容全てを読んだり、指定した文字数分読んだりすることができます。

# ファイル名を決める。
filename = 'test_read.txt'

# ファイルパスを決める。
file_path = os.path.join(os.getcwd(), filename)

# ファイルオブジェクトをwithで扱う。文字列を書き込む。
with open(file_path, mode='w', encoding='utf_8') as f:
    f.write('あいうえお\nかきくけこ\n')

# 作成したテキストをmode='r'で読む。
with open(file_path, mode='r', encoding='utf_8') as f:
    print(f.read())

    # あいうえお
    # かきくけこ
    #
    # とプリントされる。引数省略だとファイル全体を読み込む。最後の改行文字も読み込む。

with open(file_path, mode='r', encoding='utf_8') as f:
    print(f.read(3))

    # あいう
    # とプリントされる。指定されたサイズ分(文字数分)読み込む。

readlineで読み込む

readlineはファイルから1行だけ読み込みます。改行文字までを1行として読みます。

with open(file_path, mode='r', encoding='utf_8') as f:
    print(f.readline())

    # あいうえお
    #
    # とプリントされる。1行だけ読み込む。最後の改行文字も読み込む。

readlinesで読み込む

readlinesはファイル全体を行ごとに読み込み、それをリストとして返します。
1行には改行文字も含まれます。

with open(file_path, mode='r', encoding='utf_8') as f:
    print(f.readlines())

    # ['あいうえお\n', 'かきくけこ\n']
    # とプリントされる。