Если бы у меня был следующий код:
for x in range(10):
print x
Я бы получил вывод
1
2
etc..
Я хотел бы сделать это вместо печати новой строки, я хочу заменить предыдущее значение и перезаписать его новым значением в той же строке.
Если бы у меня был следующий код:
for x in range(10):
print x
Я бы получил вывод
1
2
etc..
Я хотел бы сделать это вместо печати новой строки, я хочу заменить предыдущее значение и перезаписать его новым значением в той же строке.
Один из способов - использовать символ возврата каретки ('\r'
), чтобы вернуться к началу строки, не переходя к следующей строке:
for x in range(10):
print '{0}\r'.format(x),
print
Запятая в конце инструкции печати говорит, что она не переходит к следующей строке. Последний оператор печати переходит к следующей строке, поэтому ваше приглашение не перезапишет ваш окончательный результат.
Поскольку я оказался здесь через Google, но я использую Python 3, вот как это будет работать на Python 3:
for x in range(10):
print("Progress {:2.1%}".format(x / 10), end="\r")
Связанный ответ здесь: Как я могу подавить новую строку после утверждения печати?
@Mike DeSimone ответ, вероятно, будет работать большую часть времени. Но...
for x in ['abc', 1]:
print '{}\r'.format(x),
-> 1bc
Это связано с тем, что '\r'
возвращается только в начало строки, но не очищает вывод.
Если для вас достаточно поддержки POSIX, следующее очистит текущую строку и оставьте курсор в начале:
print '\x1b[2K\r',
Он использует код выхода ANSI для очистки терминальной линии. Более подробную информацию можно найти в wikipedia и в этот отличный разговор.
Решение (не очень хорошее), которое я нашел, выглядит следующим образом:
last_x = ''
for x in ['abc', 1]:
print ' ' * len(str(last_x)) + '\r',
print '{}\r'.format(x),
last_x = x
-> 1
Одно из преимуществ заключается в том, что он будет работать и на окнах.
У меня был тот же вопрос, прежде чем вы посещали эту тему. Для меня sys.stdout.write работал только в том случае, если я правильно очищаю буфер i.e.
for x in range(10):
sys.stdout.write('\r'+str(x))
sys.stdout.flush()
Без промывки результат печатается только в конце script
Подавление новой строки и печать \r
.
print 1,
print '\r2'
или напишите в stdout:
sys.stdout.write('1')
sys.stdout.write('\r2')
Я не мог заставить какие-либо решения на этой странице работать на IPython, но небольшое отклонение от решения @Mike-Desimone выполнило задание: вместо того, чтобы завершить линию с возвратом каретки, запустите линию с возвратом каретки:
for x in range(10):
print '\r{0}'.format(x),
Кроме того, для этого подхода не требуется второй оператор печати.
Попробуй это:
import time
while True:
print("Hi ", end="\r")
time.sleep(1)
print("Bob", end="\r")
time.sleep(1)
Это сработало для меня. Часть end="\r"
заставляет перезаписать предыдущую строку.
ПРЕДУПРЕЖДЕНИЕ!
Если вы распечатаете hi
, а затем распечатаете hello
используя \r
, вы получите hillo
потому что выходные данные hillo
поверх предыдущих двух букв. Если вы распечатываете hi
с пробелами (которые здесь не отображаются), то выводится hi
. Чтобы это исправить, распечатайте пробелы, используя \r
.
for x in range(10):
time.sleep(0.5) # shows how its working
print("\r {}".format(x), end="")
time.sleep(0.5) показывает, как предыдущий вывод стирается, а новый вывод печатается "\ r", когда он находится в начале сообщения печати, он удалит предыдущий вывод перед новым выводом.
Принятый ответ не идеален. Строка, которая была напечатана первой, останется там, и если ваш второй оттиск не покрывает всю новую строку, вы получите текст мусора.
Чтобы проиллюстрировать проблему, сохраните этот код как скрипт и запустите его (или просто посмотрите):
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%
Это работает на Windows и Python 3.6
import time
for x in range(10):
time.sleep(0.5)
print(str(x)+'\r',end='')
Здесь более чистая, более "подключи и работай" версия @Nagasaki45. В отличие от многих других ответов здесь, он работает правильно со строками разной длины. Это достигается путем очистки строки с таким же количеством пробелов, как длина последней напечатанной строки. Также будет работать на Windows.
def print_statusline(msg: str):
last_msg_length = len(print_statusline.last_msg) if hasattr(print_statusline, 'last_msg') else 0
print(' ' * last_msg_length, end='\r')
print(msg, end='\r')
sys.stdout.flush() # Some say they needed this, I didn't.
print_statusline.last_msg = msg
Просто используйте это так:
for msg in ["Initializing...", "Initialization successful!"]:
print_statusline(msg)
time.sleep(1)
Этот небольшой тест показывает, что строки очищаются правильно, даже для различной длины:
for i in range(9, 0, -1):
print_statusline("{}".format(i) * i)
time.sleep(0.5)
Для создания загрузчика я использовал следующее:
for i in range(10):
print(i*'.', end='\r')
(Python3) Это то, что сработало для меня. Если вы просто используете \010, то в нем останутся символы, поэтому я немного подправил его, чтобы он переписал то, что было там. Это также позволяет вам иметь что-то перед первым элементом печати и удалять только длину элемента.
print("Here are some strings: ", end="")
items = ["abcd", "abcdef", "defqrs", "lmnop", "xyz"]
for item in items:
print(item, end="")
for i in range(len(item)): # only moving back the length of the item
print("\010 \010", end="") # the trick!
time.sleep(0.2) # so you can see what it doing
Я немного удивлен, что никто не использует символ возврата. Вот тот, который использует это.
import sys
import time
secs = 1000
while True:
time.sleep(1) #wait for a full second to pass before assigning a second
secs += 1 #acknowledge a second has passed
sys.stdout.write(str(secs))
for i in range(len(str(secs))):
sys.stdout.write('\b')
Вот мое решение! Windows 10, Python 3.7.1
Я не уверен, почему этот код работает, но он полностью стирает исходную строку. Я собрал это из предыдущих ответов. Другие ответы просто вернули бы строку в начало, но если бы после этого у вас была более короткая строка, она бы выглядела испорченной, как hello
превращается в byelo
.
import sys
#include ctypes if you're on Windows
import ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
#end ctypes
def clearline(msg):
CURSOR_UP_ONE = '\033[K'
ERASE_LINE = '\x1b[2K'
sys.stdout.write(CURSOR_UP_ONE)
sys.stdout.write(ERASE_LINE+'\r')
print(msg, end='\r')
#example
ig_usernames = ['beyonce','selenagomez']
for name in ig_usernames:
clearline("SCRAPING COMPLETE: "+ name)
Вывод - каждая строка будет переписана без какого-либо старого текста, показывающего:
SCRAPING COMPLETE: selenagomez
Следующая строка (полностью переписана в той же строке):
SCRAPING COMPLETE: beyonce
Еще один ответ, основанный на предыдущих ответах.
Содержание pbar.py: import sys, shutil, datetime
last_line_is_progress_bar=False
def print2(print_string):
global last_line_is_progress_bar
if last_line_is_progress_bar:
_delete_last_line()
last_line_is_progress_bar=False
print(print_string)
def _delete_last_line():
sys.stdout.write('\b\b\r')
sys.stdout.write(' '*shutil.get_terminal_size((80, 20)).columns)
sys.stdout.write('\b\r')
sys.stdout.flush()
def update_progress_bar(current, total):
global last_line_is_progress_bar
last_line_is_progress_bar=True
completed_percentage = round(current / (total / 100))
current_time=datetime.datetime.now().strftime('%m/%d/%Y-%H:%M:%S')
overhead_length = len(current_time+str(current))+13
console_width = shutil.get_terminal_size((80, 20)).columns - overhead_length
completed_width = round(console_width * completed_percentage / 100)
not_completed_width = console_width - completed_width
sys.stdout.write('\b\b\r')
sys.stdout.write('{}> [{}{}] {} - {}% '.format(current_time, '#'*completed_width, '-'*not_completed_width, current,
completed_percentage),)
sys.stdout.flush()
Использование скрипта:
import time
from pbar import update_progress_bar, print2
update_progress_bar(45,200)
time.sleep(1)
update_progress_bar(70,200)
time.sleep(1)
update_progress_bar(100,200)
time.sleep(1)
update_progress_bar(130,200)
time.sleep(1)
print2('some text that will re-place current progress bar')
time.sleep(1)
update_progress_bar(111,200)
time.sleep(1)
print('\n') # without \n next line will be attached to the end of the progress bar
print('built in print function that will push progress bar one line up')
time.sleep(1)
update_progress_bar(111,200)
time.sleep(1)
Вот простой код, который может быть вам полезен!
import sys
import time
for i in range(10):
sys.stdout.write("\r" + i)
sys.stdout.flush()
time.sleep(1)