Вывод на ту же строку, что и предыдущий вывод? python (2.5)

Я пишу простой 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...   

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

Как это можно сделать?

Ответ 1

Здесь код для 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

Ответ 2

Если все, что вы хотите сделать, это изменить одну строку, используйте \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)

Ответ 3

Взгляните на документацию curses module и curses module HOWTO.

Действительно основной пример:

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()

Ответ 4

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

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")

Ответ 5

Я обнаружил, что для простого оператора печати в python 2.7 просто поместите запятую в конец после '\r'.

print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!\r',

Это меньше, чем другие решения, отличные от python 3, но также более трудно поддерживать.

Ответ 6

Вы можете просто добавить '\ r' в конце строки плюс запятую в конце функции печати. Например:

print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!\r'),

Ответ 7

Я использую 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()

Ответ 8

чтобы переопределить предыдущую строку в python, все, что вам нужно, это добавить end = '\ r' в функцию печати, протестируйте этот пример:

import time
for j in range(1,5):
   print('waiting : '+j, end='\r')
   time.sleep(1)