ターミナルに表示される最後の行を常に「\ r」で書き換えることは可能ですが、コンソールに出力された前の行に戻って編集する方法があるかどうか、わかりません。
私がやりたいのは、テキストベースのRPGの複数の行を再印刷することですが、友人も、プログレスバー専用の1行とダウンロードを説明する別の行があるアプリケーションについてこれについて疑問に思っていました。
つまり、コンソールは次のように出力します。
Moving file: NameOfFile.txt
Total Progress: [######## ] 40%
次に、プログラムの実行中に(両方の行に)適切に更新します。
Unixでは、 curses モジュールを使用します。
Windowsには、いくつかのオプションがあります。
Cursesを使用した簡単な例(私は合計curses n00bです):
import curses
import time
def report_progress(filename, progress):
"""progress: 0-10"""
stdscr.addstr(0, 0, "Moving file: {0}".format(filename))
stdscr.addstr(1, 0, "Total progress: [{1:10}] {0}%".format(progress * 10, "#" * progress))
stdscr.refresh()
if __name__ == "__main__":
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
try:
for i in range(10):
report_progress("file_{0}.txt".format(i), i+1)
time.sleep(0.5)
finally:
curses.echo()
curses.nocbreak()
curses.endwin()
最終的には、画面を操作したい場合は、基本となるOSライブラリを使用する必要があります。
@codeapeからの回答は、1つのOSに固執することを気にしない場合、またはWindowsにサードパーティのライブラリをインストールすることに満足している場合、すでに多くのオプションのいくつかを提供しています。
ただし、単純にpipインストールできるクロスプラットフォームソリューションが必要な場合は、 asciimatics を使用できます。このパッケージの開発の一環として、Linux、OSX、およびWindowsで動作する単一のAPIを提供するために、環境間の違いを解決する必要がありました。
ここにPython両方のモジュールPython 2/3です)、これは数行のコードでそのような状況を簡単に解決できます; D
reprint-Python 2/3でターミナルの複数行の出力内容を印刷および更新するための単純なモジュール
そのoutput
インスタンスを通常のdict
またはlist
として扱うことができます(使用するモードによって異なります)。 output
インスタンスのコンテンツを変更すると、ターミナルの出力が自動的に更新されます:D
あなたの必要性のために、ここにコードがあります:
from reprint import output
import time
if __name__ == "__main__":
with output(output_type='dict') as output_lines:
for i in range(10):
output_lines['Moving file'] = "File_{}".format(i)
for progress in range(100):
output_lines['Total Progress'] = "[{done}{padding}] {percent}%".format(
done = "#" * int(progress/10),
padding = " " * (10 - int(progress/10)),
percent = progress
)
time.sleep(0.05)
このような:
#!/usr/bin/env python
import sys
import time
from collections import deque
queue = deque([], 3)
for t in range(20):
time.sleep(0.5)
s = "update %d" % t
for _ in range(len(queue)):
sys.stdout.write("\x1b[1A\x1b[2K") # move up cursor and delete whole line
queue.append(s)
for i in range(len(queue)):
sys.stdout.write(queue[i] + "\n") # reprint the lines
Goで書かれた Jiri プロジェクトでこれを発見しました。
さらに良い:完了後にすべての行を削除:
#!/usr/bin/env python
import sys
import time
from collections import deque
queue = deque([], 3)
t = 0
while True:
time.sleep(0.5)
if t <= 20:
s = "update %d" % t
t += 1
else:
s = None
for _ in range(len(queue)):
sys.stdout.write("\x1b[1A\x1b[2K") # move up cursor and delete whole line
if s != None:
queue.append(s)
else:
queue.popleft()
if len(queue) == 0:
break
for i in range(len(queue)):
sys.stdout.write(queue[i] + "\n") # reprint the lines