вывод в ту же строку перезаписи предыдущего вывода? python (2.5)



Я пишу простой ftp-загрузчик. Часть кода выглядит примерно так:



ftp.retrbinary("RETR " + file_name, process)


Я вызываю функцию 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...


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



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

449   6  

6 ответов:

вот код для Python 3.x:

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

The end= ключевое слово - это то, что здесь работает -- по умолчанию,print() завершается символом перевода строки (\n) символ, но его можно заменить другой строкой. В этом случае завершение строки с возвратом каретки вместо этого возвращает курсор в начало текущей строки. Таким образом, нет необходимости импортировать sys модуль для такого простого использования. print() на самом деле имеет ряд ключевых аргументов который может быть использован для значительного упрощения кода.

чтобы использовать тот же код на Python 2.6+, поместите следующую строку в верхней части файла:

from __future__ import print_function

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

посмотреть ругательства документации и модуль проклятий 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()

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

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'),

Comments

    Ничего не найдено.