Оператор печати Python ничего не печатает с возвратом каретки

Я пытаюсь написать простой инструмент, который читает файлы с диска, выполняет некоторую обработку изображений и возвращает результат алгоритма. Поскольку программа иногда может занять некоторое время, мне нравится иметь индикатор выполнения, чтобы я знал, где он находится в программе. А так как я не люблю загромождать свою командную строку и работаю на платформе Unix, я хотел использовать символ '\r' для вывода индикатора выполнения только на одной строке.

Но когда у меня есть этот код, он ничего не печатает.


# Files is a list with the filenames
for i, f in enumerate(files):
    print '\r%d / %d' % (i, len(files)),
    # Code that takes a long time

Я также пробовал:


print '\r', i, '/', len(files),

Теперь, чтобы убедиться, что это работает в python, я попробовал это:


heartbeat = 1
while True:
    print '\rHello, world', heartbeat,
    heartbeat += 1

Этот код работает отлично. В чем дело? Мое понимание возврата каретки в Linux заключалось в том, что он просто переместит символ перевода строки в начало, а затем я смогу перезаписать старый текст, который был написан ранее, если я нигде не печатаю новую строку. Хотя, похоже, этого не происходит.

Кроме того, есть ли лучший способ отобразить индикатор выполнения в командной строке, чем то, что я сейчас пытаюсь сделать?


person Jonathan Sternberg    schedule 12.05.2010    source источник
comment
pypi.python.org/pypi/progressbar   -  person kennytm    schedule 12.05.2010


Ответы (3)


Попробуйте добавить sys.stdout.flush() после оператора печати. Возможно, print не сбрасывает вывод до тех пор, пока не напишет новую строку, чего здесь не происходит.

person interjay    schedule 12.05.2010
comment
Да, это сделало это. Все еще не совсем уверен, почему пример hello world сработал. Он также не выдавал перевод строки. Может быть, потому что оператор печати работал достаточно, чтобы автоматически сбрасывать буфер после определенного количества символов? - person Jonathan Sternberg; 13.05.2010
comment
Да, он, должно быть, сбрасывал буфер, когда он заполнялся. - person interjay; 13.05.2010
comment
В качестве альтернативы можно использовать sys.stderr для немедленной печати на экране. По умолчанию stderr не буферизуется. - person amphetamachine; 16.05.2010

Обработка возврата каретки в Linux сильно различается между эмуляторами терминалов.

Обычно можно было бы использовать escape-коды терминала, которые сообщали бы эмулятору терминала, что нужно перемещать виртуальную «каретку» по экрану (представьте себе полноэкранные программы, работающие по линиям BBS). Мне известны escape-коды VT100:

\e[A: вверх
\e[B: вниз
\e[C: вправо
\e[D: влево
\e[1~: домой
\e[4~: конец

Где \e — escape-символ, \x1b.

Попробуйте заменить все \r на \e[1~

Также см. этот пост

person amphetamachine    schedule 12.05.2010

Если ваш терминал использует буферизацию строк, вам может понадобиться sys.stdout.flush(), чтобы увидеть вашу печать, если вы не выполняете перевод строки.

person Mark Tolonen    schedule 12.05.2010