モーグルとカバとパウダーの日記

モーグルやカバ(EXカービング)山スキー(BC)などがメインの日記でした。今は仕事のコンピュータ系のネタが主になっています。以前はスパム対策関連が多かったのですが最近はディープラーニング関連が多めです。

ipythonでprint等の結果がなかなか表示されない

docker上のipython上でprintとかすると、エラーも出ずでも結果も表示されず、ただ色々叩いてると突然どばーっと出力が表示される、という状況になっていました。

これは上で書いたdocker環境で起きていたため、docker環境一般でのバッファリングの問題なのかと思ったのですが、ipython依存で起きていた問題だったようです。


この問題をぐぐってみると


pythonで print の出力結果を即時表示, 強制表示, フラッシュさせる(主にjupyter) - Qiita
http://qiita.com/mmsstt/items/469a9346ce545709f53c


python - Make ipython notebook print in real time - Stack Overflow
https://stackoverflow.com/questions/29772158/make-ipython-notebook-print-in-real-time


というあたりが出てきて

  • print("hoge", flush=True) のように「flush=True」を付ける(python3.3以降)
  • sys.stdout.flush() を都度呼んでで強制フラッシュする
  • sys.stdout を書き換えて出力時に強制フラッシュする

というあたりの解決法がありました。


どれも手間で、一番最後のsys.stdout書き換えが一番現実的だったのですが、これはこれでipython起動する度にこのスクリプトを貼り付けて実行しないといけなくてあんまりでした。


が、これまたそんなことをtwitterに書いてると@tatsushi_dさんに

と教えてもらえました。
ipythonって起動時に自動的に動かすスクリプトの指定ができるとのこと!


というわけで下記のように起動時に実行するスクリプトを設定してみました。

~/.ipython/profile_default/startup/99-flushstdout.py

import sys
oldsysstdout = sys.stdout
class flushfile():
  def __init__(self, f):
    self.f = f
  def __getattr__(self,name):
    return object.__getattribute__(self.f, name)
  def write(self, x):
    self.f.write(x)
    self.f.flush()
  def flush(self):
    self.f.flush()
sys.stdout = flushfile(sys.stdout)


これで普通にprintしたら即結果が表示されるようになりました!


たったこれだけのことなのにだいぶ紆余曲折して時間使ってしまった…
でも色々と勉強になったからいいことにしよう。


でまちさんありがとうございました。