【Python】テキストファイルへの書き込み(モードw, wt)【入門第57回】
目次
- テキストファイルへの書き込み
- テキストファイルを書き込みモードで開く
- ファイルオブジェクトのタイプ
- writeメソッドで文字列を書き込む
- writelinesメソッドで文字列のリストを書き込む
- おわりに
- 関連動画
テキストファイルへの書き込み
こんにちは、narupoです。
今回も前回に引き続きファイル入出力についてです。
今回はテキストファイルへの書き込みについて解説します。
テキストファイルへの書き込みも、読み込みと同様にopen
関数で得たファイルオブジェクトのメソッドを使います。
テキストファイルへの書き込みについて、具体的には↓を見ていきます。
テキストファイルを書き込みモードで開く
ファイルオブジェクトのタイプ
writeメソッドで文字列を書き込む
writelinesメソッドで文字列のリストを書き込む
ほかのファイル入出力についての入門記事は↓をご覧ください。
- 【Python】ファイルを開いて閉じる。open関数の使い方【入門第54回】
- 【Python】テキストファイルの読み込み(モードr, rt)【入門第55回】
- 【Python】テキストファイルへの書き込み(モードw, wt)【入門第56回】
- 【Python】テキストファイルへの追記(モードa, at)【入門第57回】
- 【Python】テキストファイルを排他的に開いて書き込む(モードx, xt)【入門第58回】
- 【Python】バイナリファイルの読み込み(モードrb)【入門第59回】
- 【Python】バイナリファイルへの書き込み(モードwb)【入門第60回】
- 【Python】バイナリファイルへの追記(モードab)【入門第61回】
- 【Python】バイナリファイルを排他的に開いて書き込む(モードxb)【入門第62回】
- 【Python】テキストファイルを読み書きモードで開く(モードr+, r+t)【入門第63回】
- 【Python】テキストファイルを読み書きモードで新規作成して開く(モードw+, w+t)【入門第64回】
- 【Python】テキストファイルを読み書きモードで、新規作成して、排他的に開く(モードx+, x+t)【入門第65回】
- 【Python】バイナリファイルを読み書きモードで開く(モードr+b)【入門第66回】
- 【Python】バイナリファイルを読み書きモードで新規作成して開く(モードw+b)【入門第67回】
- 【Python】バイナリファイルを読み書きモードで排他的に開く(モードx+b)【入門第68回】
- 【Python】テキストファイルを読み書きモードで追記する(モードa+)【入門第69回】
- 【Python】バイナリファイルを読み書きモードで追記する(モードa+b)【入門第70回】
- 【Python】バイナリファイルのランダムアクセスの基本・前編【入門第71回】
- 【Python】バイナリファイルのランダムアクセスの基本・後編【入門第72回】
- 【Python】ランダムアクセスによる固定長レコードの読み書き・前編【入門第73回】
テキストファイルを書き込みモードで開く
テキストファイルを書き込みモードで開くには、open
関数の第1引数にファイルのパス、mode
引数にw
かwt
の文字列、encoding
にファイルのエンコーディングを渡します。
:::python
with open('animals.txt', mode='w', encoding='utf-8') as fout:
pass
mode
のw
はwrite
, wt
はwrite text
の略です。
open
関数は書き込みモードでファイルを開くと、ファイルが存在しなかった場合はファイルを新規作成して開きます。
また、ファイルが既に存在していた場合は、ファイルの中身を空にして開きます。
この2つは書き込みモードの特徴なので覚えておきましょう。
encoding
はテキストファイルのエンコーディングを指定します。
Windows環境だとopen
関数はデフォルトではcp932
でファイルを開こうとします。
ファイルをutf-8
で保存したい場合はencoding='utf-8'
を指定しましょう。
最近はutf-8
を推奨しているプログラムが多いのが現状です。
時代の流れなのでutf-8
を使うようにしましょう。
ちなみにLinux系の環境ではutf-8
がデフォルトになっているはずです。
乗らずにはいられない、このビッグウェーブに
open
関数の具体的な使い方については↓の記事をご覧ください。
ファイルオブジェクトのタイプ
書き込みモードで開いたテキストファイルのファイルオブジェクトのタイプは_io.TextIOWrapper
です。
:::python
with open('animals.txt', mode='w', encoding='utf-8') as fout:
print(type(fout))
↑のコードの実行結果は↓のようになります。
:::text
<class '_io.TextIOWrapper'>
このTextIOWrapper
はTextIOBase
を継承したクラスです。
さらにTextIOBase
はIOBase
を継承しています。
TextIOBase
とIOBase
の公式ドキュメントを見ればこのファイルオブジェクトで使えるメソッドを一望できます。
- io --- ストリームを扱うコアツール - TextIOBase — Python 3.7.4 ドキュメント
- io --- ストリームを扱うコアツール - IOBase — Python 3.7.4 ドキュメント
writeメソッドで文字列を書き込む
書き込みモードで開いたテキストファイルのファイルオブジェクトへ文字列を書き込むにはwrite
メソッドを使います。
たとえばファイルに文字列ネコ
を書き込むには↓のようにします。
:::python
with open('animals.txt', mode='w', encoding='utf-8') as fout:
fout.write('ネコ')
↑のコードを実行したときanimals.txt
ファイルの中身は↓のようになります。
:::text
ネコ
このとき、書き込んだ文字列が文字化けしている場合は、まず実行ファイル(スクリプト)の保存エンコーディングがutf-8
になっているか確認してください。
それからスクリプトのopen
関数のencoding
がutf-8
になっているか確認します。
最後に文字化けしているanimals.txt
を削除して、またスクリプトを実行します。
文字化けはだいたいがエンコーディングの違いが原因になっています。↓のTODOリストを見ながら確認してみてください。
実行ファイル(スクリプト)の保存エンコーディングはutf-8?
open関数のencodingはutf-8?
write
メソッドはprint
などと違って自動的に改行を付加しません。
改行を付加したい場合は制御文字である\n
を付加します。たとえば↓のようにです。
:::python
with open('animals.txt', mode='w', encoding='utf-8') as fout:
fout.write('ネコ\n')
fout.write('イヌ\n')
fout.write('サル\n')
↑のコードを実行したときanimals.txt
ファイルの中身は↓のようになります。
:::text
ネコ
イヌ
サル
flushメソッド
ファイルオブジェクトは内部でバッファ(データを溜め込む場所)を持っています。
ファイル処理ではこのバッファにデータを蓄えてから一気にファイルへ書き込むのが普通です。
たとえばwrite
メソッドに文字列を渡すと、ファイルオブジェクトはその文字列を内部のバッファに蓄えるわけです。
この「蓄えたデータを一気に書き込む」ことをフラッシュするといいます。
フラッシュのタイミングは通常はファイルが閉じられる前です。
しかし、プログラムの内容によってはこのフラッシュのタイミングを開発者側で制御したい時があります。
そういったときはflush
メソッドを使います。
flush
メソッドを使うと、ファイルオブジェクト内で蓄えられているバッファを一気にファイルへ書き込むことが出来ます。
たとえば↓のようにです。
:::python
fout = open('animals.txt', mode='w', encoding='utf-8')
fout.write('ネコ\n')
fout.write('イヌ\n')
fout.write('サル\n')
fout.flush()
察しのいい方はお気づきかもしれませんが、with
文やclose
メソッドでファイルを閉じないと、ファイルオブジェクトのバッファがファイルへ書き込まれない、つまりフラッシュされない時があります。
プログラム上では書き込んでいるはずなのに、ファイルに変更が反映されないとなったときは、このflush
メソッドの存在を思い出してみましょう。
なぜこのような設計になっているのかというと、ファイルが置かれているディスクへのアクセスと言うのはとても時間がかかるものなのです。
メモリなどに比べると、HDD
やSSD
などへのアクセス速度はウサギと亀のように違います。
そのため、ディスクへのアクセス回数を減らすためにバッファを設けて、ある程度データが溜まってからディスクへアクセスするのが効率的なんですね。
こういった仕組みはいろんなプログラミングの分野で採用されています。たとえば3DCG
のOpenGL
にもバッファの層が複数あり、それぞれデータをためることが出来るようになっています。
writelinesメソッドで文字列のリストを書き込む
文字列のリストをファイルへ書き込みたい場合はwritelines
メソッドを使います。
:::python
lines = [
'ネコ\n',
'イヌ\n',
'サル\n',
]
with open('animals.txt', mode='w', encoding='utf-8') as fout:
fout.writelines(lines)
↑のコードを実行したときanimals.txt
ファイルの中身は↓のようになります。
:::text
ネコ
イヌ
サル
writelines
メソッドも各文字列を書き込むときに改行を自動的に付加しません。
ですので↑のようにマニュアルで改行を付加します。
おわりに
テキストファイルへ文字列を書き込めるようになると、プログラムの状態をディスクに保存できるようになります。
前回のテキストファイルの読み込みと合わせると、プログラムの状態を読んだり書いたりできるようになるわけですね。
これで例えばゲームのセーブデータの読み書きも作れるようになります。
あとは日記帳などのプログラムも作れますね。
夢が広がるファイル入出力
以上、次回に続きます。
また見てね