静かなる名辞

pythonとプログラミングのこと


【python】print/pprintした結果をファイルに書き出す

まえがき

 pythonでデータ処理などを行うとき、中間出力をファイルに出力しておきたいことがよくある。

 本来ならpythonオブジェクトを出力したいならpickleを使うのが正攻法だし、そうでなくても適切なフォーマットを作って出力するのが正しいやり方。とはいえ、「テキストフォーマットで見やすいファイルを出力したい」、「必要があれば読み込んでpythonオブジェクトに戻したい」なら、printした結果をファイルに保存するのも1つの手である。この場合、listなどの簡単な組み込みオブジェクトなら、evalを使って元のオブジェクトに戻せる。

 さて、printした結果をファイルに出力する一番簡単な方法は、shellのリダイレクトを使う方法である。標準出力をファイルに書き出すことができる。

$ python ***.py > hoge.txt

 これはこれで一つの手だけど、通常のprintと併用したいときとか、もう少し細かい制御をしたいときには使えない。あくまでも簡単なプログラム限定の方法だろう。

 では、print側で出力先を制御するにはどうするのだろうか? という話をこれから書く。

 目次


スポンサーリンク



printの場合のやり方

 printはfileキーワード引数を取れる。file引数はデフォルトでは標準出力が指定されているが、実はファイルオブジェクトも指定できる。 ドキュメントによるとwriteメソッドがあるオブジェクトならなんでも渡せるらしいので、pipeにもソケットにも繋げるし、その気になればprintだけでDBにアクセスしたりwebサーバー/クライアントを作ったりすることもできるのかもしれない。たぶん実用性はないけど。

2. 組み込み関数 — Python 3.6.5 ドキュメント

 ということで、こんな感じで使えば良いだろう。

with open("hoge.txt", "w") as f:
    print(hoge_obj, file=f)

 当然ながらpython3が前提なので、python2ではこの方法は使えない。ググったらこういう記法があるらしい。

with open("hoge.txt", "w") as f:
    print >> f, hoge_obj

 ぶっちゃけ、python的ではない構文だと思うが、とにかく同じことができる。

pprintの場合は(ちょっと)違う

 みんなだいすきpprint、データを見やすく整形して出力してくれる。これもprintと同様にできると思ったら、なんとできない。

from pprint import pprint

with open("hoge.txt", "w") as file:
    pprint(hoge_obj, file=f) 
# -> TypeError: pprint() got an unexpected keyword argument 'file'

 どういうことやねんと思ってドキュメントを読みに行くと、どうやらpprintの場合はstream引数を指定してやらないといけないらしい。

8.11. pprint — データ出力の整然化 — Python 3.6.5 ドキュメント

from pprint import pprint

with open("hoge.txt", "w") as f:
    pprint(hoge_obj, stream=f)

 まあ、必ずしもファイルに出力するとは限らないので、streamの方が理にかなった命名なのかもしれない。それにしても、統一しといてくれないかな・・・と思う。

まとめ

 けっこう簡単なので、簡易的に出力したいときとかには良いと思う。

蛇足

 ググったら標準出力にファイルストリームを上書き代入するみたいな恐ろしい方法が出てきた気がする。標準出力をstdoutに戻し忘れただけで大惨事だ。
 もしかしたら昔はこの方法以外では同様のことが実現できなかったのかもしれないが、少なくとも2018年現在において敢えてこっちを使う意味はないと思う。もっとマシな方法が利用できる。