J'écris un téléchargeur FTP simple. Une partie du code ressemble à ceci:
ftp.retrbinary("RETR " + file_name, process)
j'appelle un 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/la rafraîchisse la prochaine fois pour qu'il ne le montre qu'une seule fois et que je verrai les progrès de ce téléchargement ...
Comment ceci peut être fait?
Voici le code pour Python 3.x:
print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!', end='\r')
Le mot-clé end=
Correspond au travail effectué ici. Par défaut, print()
se termine par un caractère de nouvelle ligne (\n
), Mais il peut être remplacé par une chaîne différente. Dans ce cas, la fin de la ligne avec un retour à la ligne renvoie le curseur au début de la ligne en cours. Il n’est donc pas nécessaire d’importer le module sys
pour ce type d’utilisation simple. print()
a réellement n certain nombre d'arguments de mots clés qui peuvent être utilisés pour simplifier grandement le code.
Pour utiliser le même code sur Python 2.6+, placez la ligne suivante en haut du fichier:
from __future__ import print_function
Si vous souhaitez simplement modifier une seule ligne, utilisez \r
. \r
signifie le retour chariot. Son effet est uniquement de remettre le curseur au début de la ligne en cours. Cela n'efface rien. De même, \b
peut être utilisé pour reculer d’un caractère. (certains terminaux peuvent ne pas supporter 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)
Regardez le documentation du module curses et le 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()
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")
J'ai trouvé que pour une simple instruction print dans 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 d’autres solutions non python 3, mais aussi plus difficile à maintenir.
Vous pouvez simplement ajouter '\ r' à la fin de la chaîne plus une virgule à la fin de la fonction print. Par exemple:
print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!\r'),
J'utilise spyder 3.3.1 - windows 7 - python 3.6 bien que le flush ne soit peut-être pas nécessaire. Sur la base de cette publication - 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()
pour écraser la ligne précédente dans python tout ce dont vous avez besoin est d'ajouter fin = '\ r' à la fonction d'impression, testez cet exemple:
import time
for j in range(1,5):
print('waiting : '+j, end='\r')
time.sleep(1)