Je sais qu'il est possible de réécrire de manière cohérente la dernière ligne affichée dans le terminal avec "\ r", mais j'ai du mal à déterminer s'il existe un moyen de revenir en arrière et de modifier les lignes précédentes imprimées dans la console.
Ce que je voudrais faire, c'est réimprimer plusieurs lignes pour un RPG basé sur du texte, cependant, un ami se posait également des questions à ce sujet pour une application qui avait une ligne dédiée à une barre de progression et une autre décrivant le téléchargement.
c'est-à-dire que la console imprimerait:
Moving file: NameOfFile.txt
Total Progress: [######## ] 40%
puis mettez à jour correctement (sur les deux lignes) pendant l'exécution du programme.
Sous Unix, utilisez le module curses .
Sous Windows, il existe plusieurs options:
Exemple simple utilisant des malédictions (je suis un total de malédictions n00b):
import curses
import time
def report_progress(filename, progress):
"""progress: 0-10"""
stdscr.addstr(0, 0, "Moving file: {0}".format(filename))
stdscr.addstr(1, 0, "Total progress: [{1:10}] {0}%".format(progress * 10, "#" * progress))
stdscr.refresh()
if __name__ == "__main__":
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
try:
for i in range(10):
report_progress("file_{0}.txt".format(i), i+1)
time.sleep(0.5)
finally:
curses.echo()
curses.nocbreak()
curses.endwin()
En fin de compte, si vous souhaitez manipuler l'écran, vous devez utiliser les bibliothèques de système d'exploitation sous-jacentes, qui seront généralement:
La réponse de @codeape vous donne déjà quelques-unes des nombreuses options si cela ne vous dérange pas de coller à un seul système d'exploitation ou si vous êtes heureux d'installer des bibliothèques tierces sur Windows.
Cependant, si vous voulez une solution multiplateforme que vous pouvez simplement installer par pip, vous pouvez utiliser asciimatics . Dans le cadre du développement de ce package, j'ai dû résoudre les différences entre les environnements pour fournir une API unique qui fonctionne sous Linux, OSX et Windows.
Pour les barres de progression, vous pouvez utiliser l'objet BarChart comme indiqué dans cette démo en utilisant ce code .
Voici un module Python pour les deux Python 2/3, qui peut simplement résoudre une telle situation avec quelques lignes de code; D
Vous pouvez simplement traiter cette instance output
comme une normale dict
ou list
(selon le mode que vous utilisez). Lorsque vous modifiez ce contenu dans l'instance output
, la sortie dans le terminal sera automatiquement actualisée: D
Pour votre besoin, voici le code:
from reprint import output
import time
if __name__ == "__main__":
with output(output_type='dict') as output_lines:
for i in range(10):
output_lines['Moving file'] = "File_{}".format(i)
for progress in range(100):
output_lines['Total Progress'] = "[{done}{padding}] {percent}%".format(
done = "#" * int(progress/10),
padding = " " * (10 - int(progress/10)),
percent = progress
)
time.sleep(0.05)
Comme ça:
#!/usr/bin/env python
import sys
import time
from collections import deque
queue = deque([], 3)
for t in range(20):
time.sleep(0.5)
s = "update %d" % t
for _ in range(len(queue)):
sys.stdout.write("\x1b[1A\x1b[2K") # move up cursor and delete whole line
queue.append(s)
for i in range(len(queue)):
sys.stdout.write(queue[i] + "\n") # reprint the lines
Je l'ai découvert dans le projet Jiri , écrit en Go.
Encore mieux: effacez toutes les lignes après avoir terminé:
#!/usr/bin/env python
import sys
import time
from collections import deque
queue = deque([], 3)
t = 0
while True:
time.sleep(0.5)
if t <= 20:
s = "update %d" % t
t += 1
else:
s = None
for _ in range(len(queue)):
sys.stdout.write("\x1b[1A\x1b[2K") # move up cursor and delete whole line
if s != None:
queue.append(s)
else:
queue.popleft()
if len(queue) == 0:
break
for i in range(len(queue)):
sys.stdout.write(queue[i] + "\n") # reprint the lines