Как переписать предыдущий вывод на стандартный вывод в python? - PullRequest
93 голосов
/ 24 марта 2011

Если бы у меня был следующий код:

for x in range(10):
     print x

Я бы получил вывод

1
2
etc..

То, что я хотел бы сделать, это вместо печати новой строки, я хочузамените предыдущее значение и замените его новым значением в той же строке.

Ответы [ 15 ]

99 голосов
/ 24 марта 2011

Одним из способов является использование символа возврата каретки ('\r') для возврата к началу строки без перехода на следующую строку:

for x in range(10):
    print '{0}\r'.format(x),
print

Запятая в конце оператора печатиговорит не переходить на следующую строку.Последний оператор печати переходит на следующую строку, поэтому ваше приглашение не перезапишет ваш окончательный вывод.

82 голосов
/ 18 февраля 2014

Поскольку я попал сюда через Google, но использую Python 3, вот как это будет работать в Python 3:

for x in range(10):
    print("Progress {:2.1%}".format(x / 10), end="\r")

Соответствующий ответ здесь: Как я могу подавить перевод строки после оператора print?

24 голосов
/ 03 августа 2014

@ Mike DeSimone ответ, вероятно, будет работать большую часть времени. Но ...

for x in ['abc', 1]:
    print '{}\r'.format(x),

-> 1bc

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

РЕДАКТИРОВАТЬ: Лучшее решение (чем мое старое предложение ниже)

Если вам достаточно поддержки POSIX, следующее очистит текущую строку и оставит курсор в ее начале:

print '\x1b[2K\r',

Используется управляющий код ANSI для очистки строки терминала. Больше информации можно найти в википедии и в этот великий разговор .

Старый ответ

(Не очень хорошее) решение, которое я нашел, выглядит следующим образом:

last_x = ''
for x in ['abc', 1]:
    print ' ' * len(str(last_x)) + '\r',
    print '{}\r'.format(x),
    last_x = x

-> 1

Одним из преимуществ является то, что он будет работать и на Windows.

23 голосов
/ 03 августа 2015

У меня был такой же вопрос перед посещением этой темы. Для меня sys.stdout.write работал, только если я правильно очистил буфер, т.е.

for x in range(10):
    sys.stdout.write('\r'+str(x))
    sys.stdout.flush()

Без очистки результат выводится только в конце сценария

17 голосов
/ 24 марта 2011

Подавить перевод строки и вывести \r.

print 1,
print '\r2'

или написать в стандартный вывод:

sys.stdout.write('1')
sys.stdout.write('\r2')
7 голосов
/ 23 апреля 2015

Я не смог заставить ни одно из решений на этой странице работать на IPython , но небольшое изменение в решении @ Mike-Desimone сделало свою работу: вместо завершения строки возвратом каретки, начало строка с возвратом каретки:

for x in range(10):
    print '\r{0}'.format(x),

Кроме того, этот подход не требует второго оператора печати. ​​

6 голосов
/ 20 июня 2016

Попробуйте это:

import time
while True:
    print("Hi ", end="\r")
    time.sleep(1)
    print("Bob", end="\r")
    time.sleep(1)

Это сработало для меня. Часть end="\r" перезаписывает предыдущую строку.

ВНИМАНИЕ!

Если вы распечатаете hi, а затем распечатаете hello, используя \r, вы получите hillo, потому что вывод записан поверх двух предыдущих букв. Если вы напечатаете hi с пробелами (которых здесь нет), то будет выведено hi. Чтобы это исправить, распечатайте пробелы, используя \r.

4 голосов
/ 17 июля 2018

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

Чтобы проиллюстрировать проблему, сохраните этот код как скрипт и запустите его (или просто посмотрите):

import time

n = 100
for i in range(100):
    for j in range(100):
        print("Progress {:2.1%}".format(j / 100), end="\r")
        time.sleep(0.01)
    print("Progress {:2.1%}".format(i / 100))

Вывод будет выглядеть примерно так:

Progress 0.0%%
Progress 1.0%%
Progress 2.0%%
Progress 3.0%%

Что мне подходит, так это очистить линию перед тем, как оставить постоянную печать. Не стесняйтесь приспосабливаться к вашей конкретной проблеме:

import time

ERASE_LINE = '\x1b[2K' # erase line command
n = 100
for i in range(100):
    for j in range(100):
        print("Progress {:2.1%}".format(j / 100), end="\r")
        time.sleep(0.01)
    print(ERASE_LINE + "Progress {:2.1%}".format(i / 100)) # clear the line first

И теперь он печатает, как и ожидалось:

Progress 0.0%
Progress 1.0%
Progress 2.0%
Progress 3.0%
4 голосов
/ 09 апреля 2017
for x in range(10):
    time.sleep(0.5) # shows how its working
    print("\r {}".format(x), end="")

time.sleep (0.5) показывает, как предыдущий вывод стирается и новый вывод печатается "\ r", когда он находится в начале сообщения печати, он стирает предыдущий вывод перед новым выводом.

3 голосов
/ 01 августа 2018

Это работает на Windows и Python 3.6

import time
for x in range(10):
    time.sleep(0.5)
    print(str(x)+'\r',end='')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...