English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
プロセスバーの最も大きな問題は、すべての文字が同一行にあり、変更可能であることです。
しかし、print文を実行すると、Pythonはその文を印刷した後に末尾に'\n'(改行)を追加します。これにより、ターミナルではprintの後に変更ができなくなります。したがって、現在の出力ではprintを使用することはできません。
私たちが使用するのはsysライブラリのsys.stdout.write()関数であり、この関数は文字列を出力する際に末尾に何も追加せず、このためには出力が完全には終了していないという意味です。sys.stdout.flush()関数を使用して、出力を一時的にターミナルに印刷することができます(printの疑似出力、まずは仮称します)。したがって、'r'エスケープシーケンスを使用すると、もっと理にかなったように見えますか?
つまり:文字列を出力する際に'\n'が含まれていない場合、カーソルを行の先頭に戻し、現在のバッファを表示することで、printのように見えますが、この時点でカーソルは元の位置にいます。
例
[テスト結果、Linuxターミナルで実行すると効果がありますが、pycharmでのデバッグ出力では効果がありません]
import sys, time for i in range(5) sys.stdout.write('HELLO: %05d' % i) sys.stdout.flush() time.sleep(1)
このコードをターミナルで実行すると、シンプルなプロセスバー効果が得られます。
次に解決すべき問題はまだ二つあります:
一:バッファクリア
賢い読者の中には、新しい文字列が以前よりも短い場合に問題が発生すると気づくかもしれません、例えば以下のコード:
import sys, time for i in range(5) sys.stdout.write(str(i) * (5 - i) + '\r') sys.stdout.flush() time.sleep(1)
実行してみると、期待とは異なる結果が得られました。
実際には、flushして出力された文字は自動的にクリアされません。そのため、新しい書き込みが変更されます。この点について、現在の解決策は、前の文字を空きスペースでクリアしてから再書き込みすることです:
import sys, time for i in range(5) sys.stdout.write(' ') * 10 + '\r') sys.stdout.flush() sys.stdout.write(str(i) * (5 - i) + '\r') sys.stdout.flush() time.sleep(1)
二:下端固定出力
時にはプロセスバーが読み込まれる間に他の出力があると望ましいことがあります。
前回の出力をクリアして必要な出力を出力し、仮のプロセスバーを出力するようにしましょう。
以下のコードを使用して:
import sys, time for i in range(5) sys.stdout.write(' ') * 10 + '\r') sys.stdout.flush() print i sys.stdout.write(str(i) * (5 - i) + '\r') sys.stdout.flush() time.sleep(1)
必要なタスクを完了することができます。
どうですか、実際のところ、原理はとても単純ですよね?
ここに自分で実装したクラスを示します、プロセスバーを出力するための:
import sys, time class ProgressBar: def __init__(self, count = 0, total = 0, width = 50): self.count = count self.total = total self.width = width def move(self): self.count += 1 def log(self, s): sys.stdout.write(' ') * (self.width + 9) + '\r') sys.stdout.flush() print s progress = self.width * self.count / self.total sys.stdout.write('{0:3}/{1:3}: '.format(self.count, self.total)) sys.stdout.write('#' * progress + '-' * (self.width - progress) + '\r') if progress == self.width: sys.stdout.write('\n') sys.stdout.flush() bar = ProgressBar(total = 10) for i in range(10) bar.move() bar.log('We have arrived at: ') + str(i + 1)) time.sleep(1)
効果は以下の通りです:
これにより、タスクの中でプログラムの実行進捗を簡単に確認することができます。例えば、スパイダー、機械学習など、どれくらいの時間がかかるか分からない作業でも、具体的な時間の把握ができます。
以上、Pythonでコンソールで進捗バー機能を実現するコードがすべてです。皆様に参考になれば幸いですし、もっとサポートしていただければと思います。
声明:この記事の内容はインターネットから取得しており、著作権者に帰属します。インターネットユーザーが自発的に貢献し、自己でアップロードしたものであり、このサイトは所有権を持ちません。また、人工的に編集されていないため、関連する法的責任を負いません。著作権侵害が疑われる内容がある場合は、以下のメールアドレスまでご連絡ください:notice#oldtoolbag.com(メールを送信する際には、#を@に変更してください。報告を行い、関連する証拠を提供してください。一旦確認がとりついたら、このサイトは即座に侵害される内容を削除します。)