573 votes

Barre de progression Python

Comment utiliser une barre de progression lorsque mon script effectue une tâche qui risque de prendre du temps ?

Par exemple, une fonction qui prend un certain temps pour se terminer et qui retourne True quand c'est fait. Comment puis-je afficher une barre de progression pendant l'exécution de la fonction ?

Notez que j'ai besoin que ce soit en temps réel, donc je ne sais pas comment faire. Ai-je besoin d'un thread pour ça ? Je n'en ai aucune idée.

Pour l'instant, je n'imprime rien pendant l'exécution de la fonction, mais une barre de projet serait la bienvenue. Je suis également plus intéressé par la façon dont cela peut être fait d'un point de vue du code.

0 votes

Utilisez-vous une boîte à outils GUI ou CLI uniquement ?

0 votes

CLI. Mais je peux utiliser une bibliothèque tierce, ce n'est pas un problème. Je peux le faire avec l'interface graphique, mais je suis intéressé par la partie CLI.

4 votes

Duplicata possible de Barre de progression du texte dans la console Notez que si cette question a été publiée trois jours plus tôt, la question liée est plus fréquemment consultée.

236voto

ChristopheD Points 38217

Il existe des bibliothèques spécifiques ( comme celui-là ) mais quelque chose de très simple pourrait faire l'affaire :

import time
import sys

toolbar_width = 40

# setup toolbar
sys.stdout.write("[%s]" % (" " * toolbar_width))
sys.stdout.flush()
sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '['

for i in xrange(toolbar_width):
    time.sleep(0.1) # do real work here
    # update the bar
    sys.stdout.write("-")
    sys.stdout.flush()

sys.stdout.write("\n")

21 votes

ceci n'est pas à l'échelle pour de nombreuses étapes... pypi.python.org/pypi/progress est beaucoup plus facile à utiliser

8 votes

J'ai essayé ce code, et il a jeté une NameError: name 'xrange' is not defined erreur. Est-ce qu'il me manque un module ?

8 votes

@GokuMcSpock9733 Quelle version de Python utilisez-vous ? La version 2 de Python xrange est le 3 de Python range .

109voto

Brian Khuu Points 171

Les suggestions ci-dessus sont plutôt bonnes, mais je pense que la plupart des gens veulent simplement une solution prête à l'emploi, qui ne dépende pas de paquets externes, mais qui soit également réutilisable.

J'ai obtenu les meilleurs points de tout ce qui précède, et j'en ai fait une fonction, avec des cas de test.

Pour l'utiliser, il suffit de copier les lignes sous "def update_progress(progress)" mais pas le test script. N'oubliez pas d'importer sys. Appelez cette fonction à chaque fois que vous avez besoin d'afficher ou de mettre à jour la barre de progression.

Cela fonctionne en envoyant directement le " \r "dans la console pour ramener le curseur au début. "print" en python ne reconnaît pas le symbole ci-dessus dans ce but, donc nous avons besoin de 'sys'.

import time, sys

# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
    barLength = 10 # Modify this to change the length of the progress bar
    status = ""
    if isinstance(progress, int):
        progress = float(progress)
    if not isinstance(progress, float):
        progress = 0
        status = "error: progress var must be float\r\n"
    if progress < 0:
        progress = 0
        status = "Halt...\r\n"
    if progress >= 1:
        progress = 1
        status = "Done...\r\n"
    block = int(round(barLength*progress))
    text = "\rPercent: [{0}] {1}% {2}".format( "#"*block + "-"*(barLength-block), progress*100, status)
    sys.stdout.write(text)
    sys.stdout.flush()

# update_progress test script
print "progress : 'hello'"
update_progress("hello")
time.sleep(1)

print "progress : 3"
update_progress(3)
time.sleep(1)

print "progress : [23]"
update_progress([23])
time.sleep(1)

print ""
print "progress : -10"
update_progress(-10)
time.sleep(2)

print ""
print "progress : 10"
update_progress(10)
time.sleep(2)

print ""
print "progress : 0->1"
for i in range(100):
    time.sleep(0.1)
    update_progress(i/100.0)

print ""
print "Test completed"
time.sleep(10)

Voici ce que montre le résultat du test script (La dernière barre de progression s'anime) :

progress : 'hello'
Percent: [----------] 0% error: progress var must be float
progress : 3
Percent: [##########] 100% Done...
progress : [23]
Percent: [----------] 0% error: progress var must be float

progress : -10
Percent: [----------] 0% Halt...

progress : 10
Percent: [##########] 100% Done...

progress : 0->1
Percent: [##########] 99.0%
Test completed

10 votes

Le test animé (le dernier) devrait dire in range(101) pas 100, la progression s'arrête à 99% et n'affiche jamais terminé.

0 votes

C'est une excellente réponse ! Deux suggestions : 1) vous pouvez utiliser print(..., end='') au lieu d'appeler stdout.write() + stdout.flush() . 2) si vous mettez \r à la fin de la chaîne de caractères au lieu du début, cela est beaucoup plus agréable avec les autres sorties de la console.

0 votes

comment faire pour que la barre de progression écrase chaque fois qu'elle se met à jour, au lieu d'ajouter de nouvelles lignes à la console à chaque fois ?

31voto

Essayez de progresser à partir de https://pypi.python.org/pypi/progress .

from progress.bar import Bar

bar = Bar('Processing', max=20)
for i in range(20):
    # Do some work
    bar.next()
bar.finish()

Le résultat sera une barre comme la suivante :

Processing |#############                   | 42/100

0 votes

Je viens de l'essayer. Très facile à utiliser. Il m'a fallu environ 2 minutes (y compris la progression de l'installation de pip) pour avoir une barre d'état opérationnelle.

0 votes

progress fait de belles barres, mais il échoue si d'autres logiciels manipulent stderr . désolé, mais je n'ai pas étudié le problème exact.

0 votes

Il imprime une ligne pour chaque progression dans ma console ubuntu, par exemple, si max=20, il imprime 20 lignes... Comment faire pour qu'il n'imprime qu'une seule ligne ?

26voto

Massagran Points 552

pour une application similaire (suivre la progression dans une boucle), j'ai simplement utilisé la fonction python-progressbar :

Leur exemple est le suivant,

from progressbar import *               # just a simple progress bar

widgets = ['Test: ', Percentage(), ' ', Bar(marker='0',left='[',right=']'),
           ' ', ETA(), ' ', FileTransferSpeed()] #see docs for other options

pbar = ProgressBar(widgets=widgets, maxval=500)
pbar.start()

for i in range(100,500+1,50):
    # here do something long at each iteration
    pbar.update(i) #this adds a little symbol at each iteration
pbar.finish()
print

4 votes

Pour la compatibilité avec Python 3, essayez progressbar2 paquet. Le code ci-dessus fonctionnera avec lui.

11 votes

Est-ce que tu viens vraiment d'utiliser import * ?

0 votes

@eric J'aime vivre dangereusement.

7voto

Etienne Points 6176

Utilisez cette bibliothèque : poisson

Amusez-vous bien !

0 votes

C'est possible. Vous devriez demander au développeur ou laisser un ticket : github.com/lericson/fish .

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