静かなる名辞

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


【python】行を上書きしてprintする方法

 出力の行を上書きしたいときがある。

 キャリッジリターン(\r)を使うと簡単にできるが、ちょっと難しい点もある。

方法

 簡単な例を以下のサンプルコードに示す。

import time

def main():
    for i in range(20):
        print("\r{0}".format(i), end="")
        time.sleep(0.2)
    print("")

if __name__ == "__main__":
    main()

 これを動かすと、0から19の数字が同じ行に上書きされて出力される。素晴らしい。

スポンサーリンク




 プログレスバー(のようなもの)なんかも簡単に書ける。

import time

def main():
    for i in range(10):
        print("\r[{0}] {1}/{2}".format(
            "="*(i+1)+"-"*(10-i-1) , i+1, 10), end="")
        time.sleep(0.2)
    print("")

if __name__ == "__main__":
    main()

 必要になったら積極的に使っていきたい。

駄目な方法

 実は、これはちょっと間違えると簡単にできなくなる。私はネットに転がっているサンプルコードを真似しては「できない! 駄目じゃん!」となるのを10回くらい繰り返してきたが、単に正しい方法でやっていなかっただけだった。

 結論を言うと、改行すると駄目。そしてprintはデフォルトで改行する。

import time

def main():
    for i in range(20):
        print("\r{0}".format(i))
        time.sleep(0.2)
    print("")

if __name__ == "__main__":
    main()

 これはうまく動かない。必ずend=""を指定する必要がある。これは改行を抑止するオプション(正しく説明するとendのデフォルトが改行文字で、それを空文字列に変更している)。

 上手く動かないで改行されて出てくるときは、プログラム中で改行される要素がないかどうかをよく確認してみる必要がある。

複数行を上書きしたいときは?

 ANSIエスケープシーケンスを使うとある程度の制御ができます。

ANSIエスケープコード - コンソール制御 - 碧色工房
Python - Pythonで標準出力を上書きで複数行表示させたい|teratail


 より複雑な制御を行いたい場合は、cursesなどを使ってください。

Python で Curses プログラミング — Python 3.7.4 ドキュメント

まとめ

 行を上書きできると面白いものだなぁ。