вывод в ту же строку перезаписывает предыдущий вывод?питон (2.5) - PullRequest
79 голосов
/ 04 февраля 2011

Я пишу простой загрузчик 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...   

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

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

Ответы [ 7 ]

138 голосов
/ 08 декабря 2011

Вот код для 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
36 голосов
/ 04 февраля 2011

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

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

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

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")
7 голосов
/ 27 апреля 2014

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

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

Это короче, чем в других решениях, не относящихся к Python 3, но такжеболее сложный в обслуживании.

4 голосов
/ 19 ноября 2014

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

print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!\r'),
2 голосов
/ 29 октября 2018

Я использую 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...