В Unix я могу использовать \r (возврат каретки) или \b (backspace) для перезаписи текущей строки (печать поверх текста, который уже виден) в оболочке.
Могу ли я добиться того же эффекта в командной строке Windows из скрипта Python?
Я попробовал модуль curses, но, похоже, он недоступен в Windows.






да:
import sys
import time
def restart_line():
sys.stdout.write('\r')
sys.stdout.flush()
sys.stdout.write('some data')
sys.stdout.flush()
time.sleep(2) # wait 2 seconds...
restart_line()
sys.stdout.write('other different data')
sys.stdout.flush()
Если вторые данные короче первых, символы первых данных остаются на консоли.
Простой способ, если вы просто хотите обновить предыдущую строку:
import time
for i in range(20):
print str(i) + '\r',
time.sleep(1)
В Windows (python 3) это, похоже, работает (без прямого использования stdout):
import sys
for i in reversed(range(0,20)):
time.sleep(0.1)
if (i == 19):
print(str(i), end='', file=sys.stdout)
else:
print("\r{0:{width}".format(str(i), width = w, fill = ' ', align = 'right'), end='', file=sys.stdout)
sys.stdout.flush()
w = len(str(i))
Эта же строка обновляется каждый раз при вызове функции печати.
Этот алгоритм можно улучшить, но он опубликован, чтобы показать, на что вы способны. Вы можете изменить метод в соответствии с вашими потребностями.
Это не сработает, поскольку вы определяете w после его вызова.
import sys
import time
for i in range(10):
print '\r', # print is Ok, and comma is needed.
time.sleep(0.3)
print i,
sys.stdout.flush() # flush is needed.
А если на IPython-ноутбуке, то вот так:
import time
from IPython.display import clear_output
for i in range(10):
time.sleep(0.25)
print(i)
clear_output(wait=True)
ipython notebook / jupyter - это то, что я искал!
Я знаю, что это старый, но я хотел сказать свою версию (она работает на моем ПК в cmd, но не в режиме ожидания), чтобы переопределить строку в Python 3:
>>> from time import sleep
>>> for i in range(400):
>>> print("\r" + str(i), end = "")
>>> sleep(0.5)
Обновлено: Работает в Windows и Ubuntu.
Считайте Mac OS в
По-прежнему нет решения для IDLE?
Просто у меня была эта проблема. Вы по-прежнему можете использовать \r даже в командной строке Windows, однако это вернет вас только к предыдущему разрыву строки (\n).
Если вы сделаете что-то вроде этого:
cnt = 0
print str(cnt)
while True:
cnt += 1
print "\r" + str(cnt)
Ты получишь:
0
1
2
3
4
5
...
Это потому, что \r возвращается только к последней строке. Поскольку вы уже написали символ новой строки с последним оператором печати, ваш курсор перемещается от начала новой пустой строки к началу той же новой пустой строки.
Чтобы проиллюстрировать, после того, как вы напечатаете первый 0, ваш курсор будет здесь:
0
| # <-- Cursor
Когда вы \r, вы переходите в начало строки. Но вы уже в начале очереди.
Исправление состоит в том, чтобы избежать печати символа \n, чтобы ваш курсор находился в той же строке, и \r правильно перезаписывал текст. Вы можете сделать это с помощью print 'text',. Запятая предотвращает печать символа новой строки.
cnt = 0
print str(cnt),
while True:
cnt += 1
print "\r" + str(cnt),
Теперь он правильно перезапишет строки.
Обратите внимание, что это Python 2.7, отсюда и операторы print.
Избегание новой строки точно устранило мою проблему, спасибо! В качестве дополнения в Python 3 можно использовать print(msg, end=' '), чтобы избежать новой строки.
легкий способ :)
import sys
from time import sleep
import os
#print("\033[y coordinate;[x coordinateH Hello")
os.system('cls')
sleep(0.2)
print("\033[1;1H[]")
sleep(0.2)
print("\033[1;1H []")
sleep(0.2)
print("\033[1;1H []")
sleep(0.2)
print("\033[1;1H []")
sleep(0.2)
print("\033[1;1H []")
sleep(0.2)
print("\033[1;1H []")
sleep(0.2)
print("\033[1;1H []")
sleep(0.2)
print("\033[1;1H []")
sleep(0.2)
print("\033[1;1H[]")
sleep(0.2)
Спасибо за все полезные ответы, ребята. Мне это было нужно :)
Я нашел ответ nosklo особенно полезным, но я хотел, чтобы что-то полностью содержалось в функции, передав желаемый результат в качестве параметра. Кроме того, мне действительно не нужен был таймер, так как я хотел, чтобы печать производилась после определенного события).
Вот что помогло мне, надеюсь, кому-то это пригодится:
import sys
def replace_cmd_line(output):
"""Replace the last command line output with the given output."""
sys.stdout.write(output)
sys.stdout.flush()
sys.stdout.write('\r')
sys.stdout.flush()
Вам нужен только один flush () в конце. Я не уверен, что sys.stdout.write(output + '\r') будет намного быстрее, чем вызовы двух методов (из-за выделения памяти для строки, копирования, GC), поэтому, вероятно, держать их отдельно друг от друга.
Самый простой способ - использовать два \ r - один в начале и один в конце
for i in range(10000):
print('\r'+str(round(i*100/10000))+'% Complete\r'),
Это пойдет довольно быстро
: - / Первый \r будет обработан 9999 раз зря. Если вы не знаете, где находится ваш курсор, вы можете вызвать print('\r')однажды перед циклом.
Да, этот вопрос задавали 11 лет назад, но это круто. Люблю импровизировать. Дополнение к ответу носкло:
import sys
import time
def restart_line():
sys.stdout.write("\r")
sys.stdout.flush()
string_one = "some data that is very long..."
sys.stdout.write(string_one)
sys.stdout.flush()
time.sleep(2)
restart_line()
string_two = "shorter data"
if len(string_two) < len(string_one):
string_two = string_two+(" "*int((len(string_one)-len(string_two))))
# This will overwrite the characters that would be left on the console
sys.stdout.write(string_two)
sys.stdout.flush()
Мой вопрос об индикаторе прогресса загрузки Python может быть полезным.