574 Stimmen

Textfortschrittsbalken im Terminal mit Blockzeichen

Ich habe eine einfache Konsolenanwendung zum Hoch- und Herunterladen von Dateien von einem FTP-Server unter Verwendung der ftplib geschrieben.

Ich möchte, dass die App eine Visualisierung des Download/Upload-Fortschritts für den Benutzer anzeigt; jedes Mal, wenn ein Datenpaket heruntergeladen wird, möchte ich, dass sie eine Fortschrittsaktualisierung bereitstellt, auch wenn es nur eine numerische Darstellung wie ein Prozentsatz ist.

Wichtig ist, dass ich vermeiden möchte, den gesamten Text zu löschen, der in den vorherigen Zeilen auf der Konsole ausgegeben wurde (d. h. ich möchte nicht das gesamte Terminal "löschen", während ich den aktualisierten Fortschritt ausdrucke).

Dies scheint eine ziemlich häufige Aufgabe - wie kann ich über die Erstellung eines Fortschrittsbalken oder ähnliche Visualisierung, die Ausgaben zu meiner Konsole unter Beibehaltung der vorherigen Programmausgabe gehen?

0 Stimmen

Sieht aus wie ein Duplikat dieser gestern gestellten Frage: stackoverflow.com/questions/3160699/python-progress-bar/3162864 Sie sollten also Fisch verwenden pypi.python.org/pypi/fish

37 Stimmen

"Verwenden Sie einfach eine grafische Benutzeroberfläche" verkennt, dass grafische Benutzeroberflächen in einigen Situationen (schnelle Lernkurve, Ad-hoc-Sondierungs- oder interaktive oder einmalige Aktivitäten) großartig sind, während Befehlszeilentools für andere Situationen großartig sind (erfahrene Benutzer, die Ad-hoc-Anwendungen im Handumdrehen zusammenstellen, um eine sorgfältig definierte Operation viele Male durchzuführen).

31 Stimmen

Ich habe für die Wiedereröffnung gestimmt. Die Frage scheint mir nicht zu weit gefasst zu sein.

11voto

Tux Punkte 101

Installieren Sie tqdm .( pip install tqdm ) und verwenden Sie es wie folgt:

import time
from tqdm import tqdm
for i in tqdm(range(1000)):
    time.sleep(0.01)

Das ist ein 10-Sekunden-Fortschrittsbalken, der etwa so aussieht:

47%|                     | 470/1000 [00:04<00:05, 98.61it/s]

7voto

FraggaMuffin Punkte 3446

Und, um den Haufen noch zu vergrößern, hier ist ein Objekt, das Sie verwenden können

import sys

class ProgressBar(object):
    DEFAULT_BAR_LENGTH = 65
    DEFAULT_CHAR_ON  = '='
    DEFAULT_CHAR_OFF = ' '

    def __init__(self, end, start=0):
        self.end    = end
        self.start  = start
        self._barLength = self.__class__.DEFAULT_BAR_LENGTH

        self.setLevel(self.start)
        self._plotted = False

    def setLevel(self, level):
        self._level = level
        if level < self.start:  self._level = self.start
        if level > self.end:    self._level = self.end

        self._ratio = float(self._level - self.start) / float(self.end - self.start)
        self._levelChars = int(self._ratio * self._barLength)

    def plotProgress(self):
        sys.stdout.write("\r  %3i%% [%s%s]" %(
            int(self._ratio * 100.0),
            self.__class__.DEFAULT_CHAR_ON  * int(self._levelChars),
            self.__class__.DEFAULT_CHAR_OFF * int(self._barLength - self._levelChars),
        ))
        sys.stdout.flush()
        self._plotted = True

    def setAndPlot(self, level):
        oldChars = self._levelChars
        self.setLevel(level)
        if (not self._plotted) or (oldChars != self._levelChars):
            self.plotProgress()

    def __add__(self, other):
        assert type(other) in [float, int], "can only add a number"
        self.setAndPlot(self._level + other)
        return self
    def __sub__(self, other):
        return self.__add__(-other)
    def __iadd__(self, other):
        return self.__add__(other)
    def __isub__(self, other):
        return self.__add__(-other)

    def __del__(self):
        sys.stdout.write("\n")

if __name__ == "__main__":
    import time
    count = 150
    print "starting things:"

    pb = ProgressBar(count)

    #pb.plotProgress()
    for i in range(0, count):
        pb += 1
        #pb.setAndPlot(i + 1)
        time.sleep(0.01)
    del pb

    print "done"

führt zu:

starting things:
  100% [=================================================================]
done

Dies würde man gemeinhin als "übertrieben" bezeichnen, aber es ist praktisch, wenn man es oft benutzt

0 Stimmen

Vielen Dank dafür. Kleine Korrektur, die plotProgress-Methode sollte die Zeile sys.stdout.flush() verwenden, sonst wird der Fortschrittsbalken möglicherweise nicht gezeichnet, bis die Aufgabe abgeschlossen ist (wie im Mac-Terminal).

0 Stimmen

Ich liebe das!!! Ziemlich einfach zu bedienen!!! Vielen Dank

6voto

PaulMcG Punkte 59178

Dies ausführen in der Python-Befehlszeile ( no in jeder IDE oder Entwicklungsumgebung):

>>> import threading
>>> for i in range(50+1):
...   threading._sleep(0.5)
...   print "\r%3d" % i, ('='*i)+('-'*(50-i)),

Funktioniert auf meinem Windows-System einwandfrei.

5voto

Eine sehr einfache Lösung besteht darin, diesen Code in Ihre Schleife einzufügen:

Fügen Sie dies in den Hauptteil (d.h. den Anfang) Ihrer Datei ein:

import sys

Fügen Sie dies in den Hauptteil Ihrer Schleife ein:

sys.stdout.write("-") # prints a dash for each iteration of loop
sys.stdout.flush() # ensures bar is displayed incrementally

5voto

Chris Cui Punkte 61

Versuchen Sie, dieses Paket zu installieren: pip install progressbar2 :

import time
import progressbar

for i in progressbar.progressbar(range(100)):
    time.sleep(0.02)

Fortschrittsanzeige github: https://github.com/WoLpH/python-progressbar

0 Stimmen

Der Besitzer dieses Repositorys hat bereits viel früher geantwortet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X