ファイルからのデータ読み込みを扱った前回の記事で指摘したように、ファイル操作はプロのPythonプログラマーにとって必須の知識に属しています。この機能はPython言語のコア部分であり、適切に実行するために追加のモジュールをロードする必要はありません。
Pythonでファイルを書き込むための基礎知識
ファイルを操作するための一般的なメソッドは、ファイルを開くための open()
、与えられたオフセットにファイルの現在位置を設定するための seek()
、その後ファイルを閉じるための close()
です。open()` メソッドは、ファイルオブジェクトを表すファイルハンドルを返し、これを用いてファイルにアクセスし、読み込み、書き込み、追記を行います。
ファイルへの書き込みは、データを格納するファイル名と、ファイルのアクセスモードを決定する必要があります。書き込みモードには,新しいファイルに書き込む(そして既存のデータを上書きする)モードと,すでに存在するファイルの末尾にデータを追加するモードの2つがある。省略形は “w “と “a “で、ファイルを開く前に指定する必要があります。
今回は、ファイルに一行ずつデータを書き込む方法と、行のリストとして書き込む方法、そしてファイルの末尾にデータを追加する方法を説明します。
ファイルへの1行の書き込み
この最初の例は、リスト1にあるように、一般的なプログラミング言語であるCやC++を使ったファイルへの書き込みにかなり似ています。このプロセスはとても簡単です。まず、書き込み用の open()
メソッドでファイルを開き、 write()
メソッドでファイルに1行だけ書き込み、次に close()
メソッドでファイルを閉じます。helloworld.txt “ファイルをオープンしたことにより、ファイルが存在しない場合は作成され、存在しない場合は完全に上書きされることに留意してください。
filehandle = open('helloworld.txt', 'w')
filehandle.write('Hello, world!
')
filehandle.close()
リスト1
この一連の処理は、with
ステートメントを使うことで短縮することができます。リスト2はその書き方を示しています。すでに述べたように、この方法でhelloworld.txtを開くと、ファイルがまだ存在しない場合は作成され、そうでない場合は完全に上書きされることに注意してください。
with open('helloworld.txt', 'w') as filehandle:
filehandle.write('Hello, world!
')
リスト2
行のリストをファイルに書き込む
実際には、ファイルは1行だけで構成されているわけではなく、もっと多くのデータで構成されています。したがって,ファイルの内容は,ファイルバッファを表すリストに格納されます.ファイルバッファ全体を書き込むには、writelines()
メソッドを使用します。リスト3がその例です。
filehandle = open("helloworld.txt", "w")
filebuffer = ["a first line of text", "a second line of text", "a third line"]
filehandle.writelines(filebuffer)
filehandle.close()
リスト3
リスト3のPythonプログラムを実行し、cat
コマンドを使うと、ファイル “helloworld.txt” の内容が次のようになることが分かります。
$ cat helloworld.txt
a first line of texta second line of texta third line
リスト4
これは、writelines()
メソッドがデータを書き込む際に、自動的に行の区切りを追加しないために起こります。リスト5は、行区切り文字”˶‾‾‾”を追加して1行に書き出す方法です。ジェネレーター式を使用すると、各行は行とラインセパレーターで置換されます。ここでも、with
ステートメントを使用して記述します。
with open('helloworld.txt', 'w') as filehandle:
filebuffer = ["a line of text", "another line of text", "a third line"]
filehandle.writelines("%s
" % line for line in filebuffer)
リスト5
これで、出力ファイル “helloworld.txt “はリスト6のような内容になっています。
$ cat helloworld.txt
a first line of text
a second line of text
a third line
リスト6
興味深いことに、Pythonで出力リダイレクトを使ってファイルにデータを書き込む方法があります。リスト7は、Python 2.xでそのコードを作成する方法を示しています。
# define the name of the output file
filename = "helloworld.txt"
# define content
filecontent = ["Hello, world", "a second line", "and a third line"]
with open(filename, 'w') as filehandle:
# redirect the output of print to the file handle
for line in filecontent:
print >>filehandle, line
リスト7
最新のPythonのリリースでは、これはもう同じようには動作しません。このようなことを行うには、 sys
モジュールを使用する必要があります。このモジュールによって、 sys.stdout
、 sys.stdin
、 sys.stderr
を介して UNIX の標準出力チャンネルにアクセスすることができます。この例では、まず sys.stdout
という出力チャンネルの元の値を保持し (下のコードの 8 行目)、次にそれを出力ファイルのハンドルに再定義し (15 行目)、通常通りデータを出力し (18 行目)、最後に sys.stdout
という出力チャンネルの元の値を復元して (21 行目)、出力チャンネルが終了します。リスト8はサンプルコードです。
# import sys module
import sys
# define the name of the output file
filename = "helloworld.txt"
# preserve the stdout channel
original = sys.stdout
# define content
filecontent = ["Hello, world", "a second line", "and a third line"]
with open(filename, 'w') as filehandle:
# set the new output channel
sys.stdout = filehandle
for line in filecontent:
print(line)
# restore the old output channel
sys.stdout = original
リスト8
これは必ずしもベストプラクティスではありませんが、ファイルに行を書き込むための他のオプションを提供します。
ファイルへのデータ追記
これまでは、新しいファイルにデータを格納したり、既存のファイルにデータを上書きして格納したりしてきました。しかし、既存のファイルの末尾にデータを追加したい場合はどうすればよいのでしょうか。この場合、既存のファイルを別のアクセスモードを使って開く必要がある。ここでは、’w’の代わりに’a’に変更します。リスト9は、その処理方法を示しています。リスト10でも同じことができますが、こちらはむしろ with
ステートメントを使用しています。
filehandle = open('helloworld.txt','a')
filehandle.write('
' + 'Hello, world!
')
filehandle.close()
リスト9
with open('helloworld.txt', 'a') as filehandle:
filehandle.write('
' + 'Hello, world!
')
リスト10
先ほどと同じhelloworld.txtを使用して、このコードを実行すると、次のようなファイルコンテンツが生成されます。
$ cat helloworld.txt
Hello, world
a second line
and a third line
Hello, world!
結論
Pythonでは、ファイルへのプレーンテキストデータの書き込みや、既存のファイルへのデータの追記は、ファイルからの読み込みと同じくらい簡単です。データを書き込んだり追加したりした後にファイルが閉じられるとすぐに、Pythonは同期呼び出しをトリガします。その結果、更新されたファイルは直ちにディスクに書き込まれます。
参考文献
- Frank Hofmann: Python でファイルを読む
- Python 101: 標準出力をリダイレクトする
謝辞
Zoleka Hatitongweのサポートに感謝する。