Заменить вывод консоли в Python
мне интересно, как я мог бы создать один из этих отличных счетчиков консоли в Python, как в некоторых C/C++-программах.
у меня есть петли и выход по току по линиям:
Doing thing 0
Doing thing 1
Doing thing 2
...
что было бы аккуратнее было бы просто иметь последнюю строку обновления;
X things done.
Я видел это в ряде консольных программ и интересно, если/как я бы сделал это в Python.
7 ответов:
простое решение-это просто писать
"\r"
перед строкой и не добавляя новую строку; если строка никогда не становится короче, этого достаточно...sys.stdout.write("\rDoing thing %i" % i) sys.stdout.flush()
немного более сложным является индикатор выполнения... это то, что я использую:
def startProgress(title): global progress_x sys.stdout.write(title + ": [" + "-"*40 + "]" + chr(8)*41) sys.stdout.flush() progress_x = 0 def progress(x): global progress_x x = int(x * 40 // 100) sys.stdout.write("#" * (x - progress_x)) sys.stdout.flush() progress_x = x def endProgress(): sys.stdout.write("#" * (40 - progress_x) + "]\n") sys.stdout.flush()
вы называете
startProgress
передавая описание операции, затемprogress(x)
здесьx
процент и, наконец,endProgress()
более элегантное решение может быть:
def progressBar(value, endvalue, bar_length=20): percent = float(value) / endvalue arrow = '-' * int(round(percent * bar_length)-1) + '>' spaces = ' ' * (bar_length - len(arrow)) sys.stdout.write("\rPercent: [{0}] {1}%".format(arrow + spaces, int(round(percent * 100)))) sys.stdout.flush()
вызвать эту функцию со значением и endvalue, результат должен быть
Percent: [-------------> ] 69%
другой ответ может быть лучше, но вот что я делал. Во-первых, я сделал функцию под названием Прогресс, которая выводит символ backspace:
def progress(x): out = '%s things done' % x # The output bs = '\b' * 1000 # The backspace print bs, print out,
затем я вызвал его в цикле в моей основной функции следующим образом:
def main(): for x in range(20): progress(x) return
Это, конечно, стереть всю строку, но вы можете возиться с ним, чтобы сделать именно то, что вы хотите. Я в конечном итоге сделать индикатор выполнения с помощью этого метода.
для тех, кто натыкается на это годы спустя (как и я), я немного изменил методы 6502, чтобы позволить индикатору прогресса уменьшаться, а также увеличиваться. Полезно в несколько большем количестве случаев. Спасибо 6502 за отличный инструмент!
в принципе, единственное различие заключается в том, что вся строка #s и-s записывается каждый раз, когда вызывается прогресс(x), и курсор всегда возвращается в начало бара.
def startprogress(title): """Creates a progress bar 40 chars long on the console and moves cursor back to beginning with BS character""" global progress_x sys.stdout.write(title + ": [" + "-" * 40 + "]" + chr(8) * 41) sys.stdout.flush() progress_x = 0 def progress(x): """Sets progress bar to a certain percentage x. Progress is given as whole percentage, i.e. 50% done is given by x = 50""" global progress_x x = int(x * 40 // 100) sys.stdout.write("#" * x + "-" * (40 - x) + "]" + chr(8) * 41) sys.stdout.flush() progress_x = x def endprogress(): """End of progress bar; Write full bar, then move to next line""" sys.stdout.write("#" * 40 + "]\n") sys.stdout.flush()
Если я хорошо понял (не уверен), вы хотите напечатать с помощью
<CR>
, а не<LR>
?Если это возможно, пока консольный терминал позволяет это (он сломается, когда выход si перенаправляется в файл).
from __future__ import print_function print("count x\r", file=sys.stdout, end=" ")
In python 3 вы можете сделать это, чтобы напечатать на одной строке:
print('', end='\r')
особенно полезно отслеживать последние обновления и прогресса.
Я бы также рекомендовал tqdmотсюда если кто-то хочет увидеть ход цикла. Он печатает текущую итерацию и общее количество итераций в виде строки прогрессии с ожидаемым временем завершения. Супер полезно и быстро. Работает для python2 и python3.
добавил немного больше функциональности в пример Аравинд Воггу:
def progressBar(name, value, endvalue, bar_length = 50, width = 20): percent = float(value) / endvalue arrow = '-' * int(round(percent*bar_length) - 1) + '>' spaces = ' ' * (bar_length - len(arrow)) sys.stdout.write("\r{0: <{1}} : [{2}]{3}%".format(\ name, width, arrow + spaces, int(round(percent*100)))) sys.stdout.flush() if value == endvalue: sys.stdout.write('\n\n')
теперь вы можете генерировать несколько progressbars без замены один раз раньше.
Я также добавил имя как значение с фиксированной шириной.для двух циклов и двух раз использования progressBar () результат будет выглядеть например: