Пишу загрузчик FTP. Часть кода выглядит примерно так:
ftp.retrbinary("RETR " + file_name, process)
Я вызываю функциональный процесс для обработки обратного вызова:
def process(data):
print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
file.write(data)
и вывод будет примерно таким:
1784 KB / KB 1829 downloaded!
1788 KB / KB 1829 downloaded!
etc...
но я хочу, чтобы он распечатал эту строку и в следующий раз перепечатал / обновил ее, чтобы она отображалась только один раз, и я буду видеть прогресс этой загрузки.
Как это сделать?
python
refresh
progress-bar
Кристиан
источник
источник
Ответы:
Вот код для Python 3.x:
print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!', end='\r')
Здесь работает
end=
ключевое слово - по умолчаниюprint()
оканчивается символом новой строки (\n
), но его можно заменить другой строкой. В этом случае завершение строки символом возврата каретки возвращает курсор в начало текущей строки. Таким образом, нет необходимости импортироватьsys
модуль для такого простого использования.print()
на самом деле имеет ряд аргументов ключевого слова, которые можно использовать для значительного упрощения кода.Чтобы использовать тот же код в Python 2.6+, поместите следующую строку вверху файла:
from __future__ import print_function
источник
from __future__ import print_function
.print "foo",
однако вам все равно нужно промывать после этого, чтобы увидеть изменение:sys.stdout.flush()
\r
в начало строки и установитьend=''
вместо этого, чтобы это работало. Не думаю, что моему терминалу нравится, когда я заканчиваю\r
flush=True
кprint()
функции, чтобы буфер был очищен (стандартный строчный буфер будет очищаться только при записи\n
новой строки).\r
в началеend=''
работало лучше всего и плавнее. Использованиеflush=True
с\r
в конце, если строка иend='\r'
также работали, но не были гладкими и стирали линию и ее перевод строки.Если все, что вам нужно сделать, это изменить одну строку, используйте
\r
.\r
означает возврат каретки. Его эффект заключается исключительно в том, чтобы вернуть курсор в начало текущей строки. Ничего не стирает. Точно так же\b
можно использовать для перехода на один символ назад. (некоторые терминалы могут не поддерживать все эти функции)import sys def process(data): size_str = os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!' sys.stdout.write('%s\r' % size_str) sys.stdout.flush() file.write(data)
источник
\r
означает возврат каретки. его эффект заключается исключительно в том, чтобы вернуть курсор в начало текущей строки. он ничего не стирает. аналогично,\b
можно использовать для перехода на один символ назад. (некоторые терминалы могут не поддерживать все эти функции)sys.stdout.write('%s\r', size_str')
Я думаю, вы имели в виду,sys.stdout.write('%s\r' % size_str)
но это не работает.print
вместо,sys.stdout.write
если хотите:print size_str + "\r",
работает нормально. Знак,
в конце оператора печати подавляет перевод строки;sys.stdout.flush()
по-прежнему нуженПосмотрите документацию модуля curses и HOWTO модуля curses .
Действительно базовый пример:
import time import curses stdscr = curses.initscr() stdscr.addstr(0, 0, "Hello") stdscr.refresh() time.sleep(1) stdscr.addstr(0, 0, "World! (with curses)") stdscr.refresh()
источник
clrtoeol
для , когда вторая линия короче , чем первый.Вот мой маленький класс, который может перепечатывать блоки текста. Он правильно очищает предыдущий текст, поэтому вы можете перезаписать старый текст более коротким новым текстом, не создавая беспорядка.
import re, sys class Reprinter: def __init__(self): self.text = '' def moveup(self, lines): for _ in range(lines): sys.stdout.write("\x1b[A") def reprint(self, text): # Clear previous text by overwritig non-spaces with spaces self.moveup(self.text.count("\n")) sys.stdout.write(re.sub(r"[^\s]", " ", self.text)) # Print new text lines = min(self.text.count("\n"), text.count("\n")) self.moveup(lines) sys.stdout.write(text) self.text = text reprinter = Reprinter() reprinter.reprint("Foobar\nBazbar") reprinter.reprint("Foo\nbar")
источник
Я обнаружил, что для простого оператора печати в python 2.7 просто поставьте запятую в конце после вашего
'\r'
.print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!\r',
Это короче, чем другие решения, отличные от Python 3, но и сложнее в обслуживании.
источник
Вы можете просто добавить '\ r' в конец строки плюс запятую в конце функции печати. Например:
print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!\r'),
источник
end
параметром по умолчанию, установленным\n
так, чтобы печатать(...)KB downloaded!\r\n
. Я ошибся?end = '\r'
вместо этого устраняет проблему в Python 3.Я использую spyder 3.3.1 - windows 7 - python 3.6, хотя промывка может не понадобиться. на основе этой публикации - https://github.com/spyder-ide/spyder/issues/3437
#works in spyder ipython console - \r at start of string , end="" import time import sys for i in range(20): time.sleep(0.5) print(f"\rnumber{i}",end="") sys.stdout.flush()
источник
чтобы переопределить предыдущую строку в python, все, что вам нужно, это добавить end = '\ r' в функцию печати, проверьте этот пример:
import time for j in range(1,5): print('waiting : '+j, end='\r') time.sleep(1)
источник