159 votes

Sortie sur la même ligne écrasant la sortie précédente ?

J'écris un téléchargeur FTP. Une partie du code ressemble à ceci :

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

J'appelle le processus de fonction pour gérer le rappel :

 def process(data):
    print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
    file.write(data)

et la sortie est quelque chose comme ceci:

 1784  KB / KB 1829 downloaded!
1788  KB / KB 1829 downloaded!
etc...   

mais je veux qu'il imprime cette ligne et la réimprime/actualise la prochaine fois pour qu'il ne l'affiche qu'une seule fois et je verrai la progression de ce téléchargement.

Comment ceci peut être fait?

48voto

sdolan Points 15572

Si tout ce que vous voulez faire est de changer une seule ligne, utilisez \r . \r signifie retour chariot. Son effet est uniquement de remettre le curseur au début de la ligne courante. Il n'efface rien. De même, \b peut être utilisé pour reculer d'un caractère. (certains terminaux peuvent ne pas prendre en charge toutes ces fonctionnalités)

 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)

18voto

Andrea Spadaccini Points 4755

Jetez un œil à la documentation du module curses et au module curses HOWTO .

Exemple vraiment basique :

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

13voto

Bouke Versteegh Points 199

Voici ma petite classe qui peut réimprimer des blocs de texte. Il efface correctement le texte précédent afin que vous puissiez écraser votre ancien texte avec un nouveau texte plus court sans créer de désordre.

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

8voto

Matt Ellen Points 5270

J'ai trouvé que pour une simple instruction print en python 2.7, il suffit de mettre une virgule à la fin après votre '\r' .

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

C'est plus court que les autres solutions non Python 3, mais aussi plus difficile à maintenir.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X