2010-06-08 3 views
100

Чтобы реализовать строку состояния, как показано ниже:Python, чтобы распечатать строку состояния и процент

[==========    ] 45% 
[================   ] 60% 
[==========================] 100% 

Я хочу, чтобы это был распечатан на стандартный вывод, и держать его освежающее, не печатать на другую линию. Как это сделать?

ответ

86

Существует модуль Python, который вы можете получить от PyPI под названием progressbar, который реализует такую ​​функциональность. Если вы не возражаете добавить зависимость, это хорошее решение. В противном случае перейдите к одному из других ответов.

Простой пример того, как использовать его:

import progressbar 
from time import sleep 
bar = progressbar.ProgressBar(maxval=20, \ 
    widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()]) 
bar.start() 
for i in xrange(20): 
    bar.update(i+1) 
    sleep(0.1) 
bar.finish() 

Чтобы установить его, вы можете использовать easy_install progressbar или pip install progressbar, если вы предпочитаете пип.

+0

Все ответы являются замечательными, однако мне больше нравится модуль. Спасибо всем. – Stan

+3

Или, может быть, более классная альтернатива: http://pypi.python.org/pypi/fish/ –

+0

К сожалению, ни «progressbar», ни «fish», похоже, не работают с python3. –

17

Вы можете использовать \r (carriage return). Демонстрация:

import sys 
total = 10000000 
point = total/100 
increment = total/20 
for i in xrange(total): 
    if(i % (5 * point) == 0): 
     sys.stdout.write("\r[" + "=" * (i/increment) + " " * ((total - i)/ increment) + "]" + str(i/point) + "%") 
     sys.stdout.flush() 
+0

Try 'total' как' 10', то вы получите сообщение об ошибке 'ZeroDivisionError: длинное деление или по модулю по zero' –

172

'\r' символа (возврат каретки) сбрасывает курсор в начало строки и позволяет писать над тем, что было раньше на линии.

from time import sleep 
import sys 

for i in range(21): 
    sys.stdout.write('\r') 
    # the exact output you're looking for: 
    sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i)) 
    sys.stdout.flush() 
    sleep(0.25) 

Я не 100% уверен, что это полностью переносимы во всех системах, но она работает на Linux и OSX по крайней мере.

+7

это работает на окнах тоже. –

+0

Очень приятно, сэр. –

+2

Это лучше, чем отмеченный ответ, потому что он также работает с Python 3. –

11

Здесь вы можете использовать следующий код в функции:

def drawProgressBar(percent, barLen = 20): 
    sys.stdout.write("\r") 
    progress = "" 
    for i in range(barLen): 
     if i < int(barLen * percent): 
      progress += "=" 
     else: 
      progress += " " 
    sys.stdout.write("[ %s ] %.2f%%" % (progress, percent * 100)) 
    sys.stdout.flush() 
+0

Для меня первая строка не изменяется с помощью курсора - только вторая строка делает. Следовательно, несколько строк, полученных для индикатора выполнения, и один для, например, '] процентов * 100%' –

5

на основе вышеуказанных ответов и другие аналогичные вопросы о ходе CLI-бар, я думаю, что я получил общий общий ответ на все из них. Проверьте это на https://stackoverflow.com/a/15860757/2254146

Вот копия функции, но изменен, чтобы соответствовать вашему стилю:

import time, sys 

# update_progress() : Displays or updates a console progress bar 
## Accepts a float between 0 and 1. Any int will be converted to a float. 
## A value under 0 represents a 'halt'. 
## A value at 1 or bigger represents 100% 
def update_progress(progress): 
    barLength = 20 # Modify this to change the length of the progress bar 
    status = "" 
    if isinstance(progress, int): 
     progress = float(progress) 
    if not isinstance(progress, float): 
     progress = 0 
     status = "error: progress var must be float\r\n" 
    if progress < 0: 
     progress = 0 
     status = "Halt...\r\n" 
    if progress >= 1: 
     progress = 1 
     status = "Done...\r\n" 
    block = int(round(barLength*progress)) 
    text = "\rPercent: [{0}] {1}% {2}".format("="*block + " "*(barLength-block), progress*100, status) 
    sys.stdout.write(text) 
    sys.stdout.flush() 

Похоже

Процент: [=========== =========] 99.0%

+0

Индикатор выполнения не отображается для меня –

48

Я нашел полезную библиотеку tqdm (https://github.com/tqdm/tqdm/, ранее: https://github.com/noamraph/tqdm). Он автоматически оценивает время завершения и может использоваться как итератор.

Использование:

import tqdm 
import time 

for i in tqdm.tqdm(range(1000)): 
    time.sleep(0.01) 
    # or other long operations 

Результаты в:

|####------| 450/1000 45% [elapsed: 00:04 left: 00:05, 99.15 iters/sec] 

tqdm может обернуть любую итерацию.

+3

Теперь проект tqdm поддерживается здесь (https://github.com/tqdm/ tqdm /) новой командой разработчиков. – gaborous

+0

waw, этот tqdm просто потрясающий, и так прост в использовании :). – Sidahmed

+1

это легко самое простое решение – kd88

2

Основываясь на некоторых ответах здесь и в других местах, я написал эту простую функцию, которая отображает индикатор выполнения и истекшее/оцененное оставшееся время. Должен работать на большинстве машин на базе UNIX.

import time 
import sys 

percent = 50.0 
start = time.time() 
draw_progress_bar(percent, start) 


def draw_progress_bar(percent, start, barLen=20): 
sys.stdout.write("\r") 
progress = "" 
for i in range(barLen): 
    if i < int(barLen * percent): 
     progress += "=" 
    else: 
     progress += " " 

elapsedTime = time.time() - start; 
estimatedRemaining = int(elapsedTime * (1.0/percent) - elapsedTime) 

if (percent == 1.0): 
    sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: Done!\n" % 
     (progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60)) 
    sys.stdout.flush() 
    return 
else: 
    sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: %im%02is " % 
     (progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60, 
     estimatedRemaining/60, estimatedRemaining%60)) 
    sys.stdout.flush() 
    return 
1

Я пришел на эту тему сегодня, и после того, как пытались это решение от Марка Rushakoff

from time import sleep 
import sys 

for i in range(21): 
sys.stdout.write('\r') 
# the exact output you're looking for: 
sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i)) 
sys.stdout.flush() 
sleep(0.25) 

Я могу сказать, что это отлично работает на W7-64 с питоном 3.4.3 64-битный, но только на родной консоли. Однако при использовании встроенной консоли spyder 3.0.0dev разрывы строк остаются/снова присутствуют. Поскольку это заняло у меня некоторое время, чтобы понять, я хотел бы сообщить об этом наблюдении здесь.

2

Это довольно простой подход, который можно использовать с любым циклом.

#!/usr/bin/python 
for i in range(100001): 
    s = ((i/5000)*'#')+str(i)+(' %') 
    print ('\r'+s), 
+0

Что делает '#'? –

+0

@unseen_rider Здесь '#' - это просто символ, который будет повторяться по мере увеличения итерации цикла. –

2

Если вы разрабатываете интерфейс командной строки, я предлагаю вам взглянуть на click что очень приятно:

import click 
import time 

for filename in range(3): 
    with click.progressbar(range(100), fill_char='=', empty_char=' ') as bar: 
     for user in bar: 
      time.sleep(0.01) 

Здесь выход вы получите:

$ python test.py 
    [====================================] 100% 
    [====================================] 100% 
    [=========       ] 27% 
0

Попробуйте PyProg. PyProg - это библиотека с открытым исходным кодом для Python для создания супер настраиваемых индикаторов прогресса & баров.

В настоящее время он находится в версии 1.0.2; он размещен на Github и доступен на PyPI (ссылки ниже). Он совместим с Python 3 & 2 и может также использоваться с Qt Console.

Очень прост в использовании. Следующий код:

import pyprog 
from time import sleep 

# Create Object 
prog = pyprog.ProgressBar(" ", " ", total=34, bar_length=26, complete_symbol="=", not_complete_symbol=" ", wrap_bar_prefix=" [", wrap_bar_suffix="] ", progress_explain="", progress_loc=pyprog.ProgressBar.PROGRESS_LOC_END) 
# Update Progress Bar 
prog.update() 

for i in range(34): 
    # Do something 
    sleep(0.1) 
    # Set current status 
    prog.set_stat(i + 1) 
    # Update Progress Bar again 
    prog.update() 

# Make the Progress Bar final 
prog.end() 

будет производить именно то, что вы хотите (даже длину бара!):

[===========    ] 45% 
[===============   ] 60% 
[==========================] 100% 

Для больше опций для настройки индикатора выполнения, перейдите на страницу Github этого сайта.

Я на самом деле сделал PyProg, потому что мне нужна простая, но супер настраиваемая библиотека показателей хода. Вы можете легко установить его с помощью: pip install pyprog.

PyProg Github: https://github.com/Bill13579/pyprog
PyPI: https://pypi.python.org/pypi/pyprog/

Смежные вопросы