【Python】テキストファイルへの書き込み(モードw, wt)【入門第57回】

178, 2019-09-16

目次

テキストファイルへの書き込み

こんにちは、narupoです。

今回も前回に引き続きファイル入出力についてです。
今回はテキストファイルへの書き込みについて解説します。
テキストファイルへの書き込みも、読み込みと同様にopen関数で得たファイルオブジェクトのメソッドを使います。

テキストファイルへの書き込みについて、具体的には↓を見ていきます。

  • テキストファイルを書き込みモードで開く
  • ファイルオブジェクトのタイプ
  • writeメソッドで文字列を書き込む
  • writelinesメソッドで文字列のリストを書き込む

ほかのファイル入出力についての入門記事は↓をご覧ください。

テキストファイルを書き込みモードで開く

テキストファイルを書き込みモードで開くには、open関数の第1引数にファイルのパス、mode引数にwwtの文字列、encodingにファイルのエンコーディングを渡します。

with open('animals.txt', mode='w', encoding='utf-8') as fout:
    pass

modewwrite, wtwrite textの略です。
open関数は書き込みモードでファイルを開くと、ファイルが存在しなかった場合はファイルを新規作成して開きます
また、ファイルが既に存在していた場合は、ファイルの中身を空にして開きます
この2つは書き込みモードの特徴なので覚えておきましょう。

encodingはテキストファイルのエンコーディングを指定します。
Windows環境だとopen関数はデフォルトではcp932でファイルを開こうとします。
ファイルをutf-8で保存したい場合はencoding='utf-8'を指定しましょう。

最近はutf-8を推奨しているプログラムが多いのが現状です。
時代の流れなのでutf-8を使うようにしましょう。
ちなみにLinux系の環境ではutf-8がデフォルトになっているはずです。

乗らずにはいられない、このビッグウェーブに

open関数の具体的な使い方については↓の記事をご覧ください。

ファイルオブジェクトのタイプ

書き込みモードで開いたテキストファイルのファイルオブジェクトのタイプは_io.TextIOWrapperです。

with open('animals.txt', mode='w', encoding='utf-8') as fout:
    print(type(fout))

↑のコードの実行結果は↓のようになります。

<class '_io.TextIOWrapper'>

このTextIOWrapperTextIOBaseを継承したクラスです。
さらにTextIOBaseIOBaseを継承しています。
TextIOBaseIOBaseの公式ドキュメントを見ればこのファイルオブジェクトで使えるメソッドを一望できます。

writeメソッドで文字列を書き込む

書き込みモードで開いたテキストファイルのファイルオブジェクトへ文字列を書き込むにはwriteメソッドを使います。
たとえばファイルに文字列ネコを書き込むには↓のようにします。

with open('animals.txt', mode='w', encoding='utf-8') as fout:
    fout.write('ネコ')

↑のコードを実行したときanimals.txtファイルの中身は↓のようになります。

ネコ

このとき、書き込んだ文字列が文字化けしている場合は、まず実行ファイル(スクリプト)の保存エンコーディングがutf-8になっているか確認してください。
それからスクリプトのopen関数のencodingutf-8になっているか確認します。
最後に文字化けしているanimals.txtを削除して、またスクリプトを実行します。
文字化けはだいたいがエンコーディングの違いが原因になっています。↓のTODOリストを見ながら確認してみてください。

  • 実行ファイル(スクリプト)の保存エンコーディングはutf-8?
  • open関数のencodingはutf-8?

writeメソッドはprintなどと違って自動的に改行を付加しません。
改行を付加したい場合は制御文字である\nを付加します。たとえば↓のようにです。

with open('animals.txt', mode='w', encoding='utf-8') as fout:
    fout.write('ネコ\n')
    fout.write('イヌ\n')
    fout.write('サル\n')

↑のコードを実行したときanimals.txtファイルの中身は↓のようになります。

ネコ
イヌ
サル

flushメソッド

ファイルオブジェクトは内部でバッファ(データを溜め込む場所)を持っています。
ファイル処理ではこのバッファにデータを蓄えてから一気にファイルへ書き込むのが普通です。
たとえばwriteメソッドに文字列を渡すと、ファイルオブジェクトはその文字列を内部のバッファに蓄えるわけです。
この「蓄えたデータを一気に書き込む」ことをフラッシュするといいます。

フラッシュのタイミングは通常はファイルが閉じられる前です。
しかし、プログラムの内容によってはこのフラッシュのタイミングを開発者側で制御したい時があります。
そういったときはflushメソッドを使います。
flushメソッドを使うと、ファイルオブジェクト内で蓄えられているバッファを一気にファイルへ書き込むことが出来ます。
たとえば↓のようにです。

fout = open('animals.txt', mode='w', encoding='utf-8')
fout.write('ネコ\n')
fout.write('イヌ\n')
fout.write('サル\n')
fout.flush()

察しのいい方はお気づきかもしれませんが、with文やcloseメソッドでファイルを閉じないと、ファイルオブジェクトのバッファがファイルへ書き込まれない、つまりフラッシュされない時があります。
プログラム上では書き込んでいるはずなのに、ファイルに変更が反映されないとなったときは、このflushメソッドの存在を思い出してみましょう。

なぜこのような設計になっているのかというと、ファイルが置かれているディスクへのアクセスと言うのはとても時間がかかるものなのです。
メモリなどに比べると、HDDSSDなどへのアクセス速度はウサギと亀のように違います。
そのため、ディスクへのアクセス回数を減らすためにバッファを設けて、ある程度データが溜まってからディスクへアクセスするのが効率的なんですね。
こういった仕組みはいろんなプログラミングの分野で採用されています。たとえば3DCGOpenGLにもバッファの層が複数あり、それぞれデータをためることが出来るようになっています。

writelinesメソッドで文字列のリストを書き込む

文字列のリストをファイルへ書き込みたい場合はwritelinesメソッドを使います。

lines = [
    'ネコ\n',
    'イヌ\n',
    'サル\n',
]

with open('animals.txt', mode='w', encoding='utf-8') as fout:
    fout.writelines(lines)

↑のコードを実行したときanimals.txtファイルの中身は↓のようになります。

ネコ
イヌ
サル

writelinesメソッドも各文字列を書き込むときに改行を自動的に付加しません。
ですので↑のようにマニュアルで改行を付加します。

おわりに

テキストファイルへ文字列を書き込めるようになると、プログラムの状態をディスクに保存できるようになります。
前回のテキストファイルの読み込みと合わせると、プログラムの状態を読んだり書いたりできるようになるわけですね。
これで例えばゲームのセーブデータの読み書きも作れるようになります。
あとは日記帳などのプログラムも作れますね。

夢が広がるファイル入出力

以上、次回に続きます。

また見てね

関連動画







姉妹ブログを見に行く。

スポンサーリンク

スポンサーリンク

スポンサーリンク

スポンサーリンク