it-swarm.com.de

Drucken Sie in dieselbe Zeile und nicht in eine neue Zeile in Python

Im Grunde möchte ich das Gegenteil von dem tun, was dieser Kerl getan hat ... hehe.

Python-Skript: Neue Zeile jedes Mal in Shell drucken, statt vorhandene Zeile zu aktualisieren

Ich habe ein Programm, das mir sagt, wie weit es ist.

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete"

Wenn also len (some_list) 50 wäre, würde ich die letzte Zeile 50 Mal drucken lassen. Ich möchte eine Zeile drucken und diese Zeile aktualisieren. Ich weiß, ich weiß, das ist wahrscheinlich die kleinste Frage, die Sie den ganzen Tag lesen werden. Ich kann einfach nicht die vier Wörter herausfinden, die ich in google eingeben muss, um die Antwort zu erhalten.

Aktualisieren! Ich habe Mvds 'Vorschlag ausprobiert, der richtig war. Der neue Code

print percent_complete,"           \r",

Percent Complete ist nur eine Zeichenkette (ich habe jetzt zum ersten Mal abstrahiert, als ich versuchte, wörtlich zu sein). Das Ergebnis ist nun, dass das Programm ausgeführt wird, erst nach Beendigung des Programms wird ALLES gedruckt und dann in einer einzigen Zeile "100 Prozent abgeschlossen" ausgegeben.

Ohne den Wagenrücklauf (aber mit Komma, die Hälfte von mvds 'Vorschlag) wird bis zum Ende nichts gedruckt. Und druckt dann:

0 percent complete     2 percent complete     3 percent complete     4 percent complete    

Und so weiter. Nun ist das neue Problem, dass mit dem Komma nicht gedruckt wird, bis das Programm beendet ist.

Mit dem Wagenrücklauf und ohne Komma verhält es sich genauso wie mit keinem von beiden.

55
chriscauley

Es wird Wagenrücklauf oder \r genannt.

Benutzen

print i/len(some_list)*100," percent complete         \r",

Das Komma verhindert, dass beim Druck eine neue Zeile hinzugefügt wird. (und die Leerzeichen halten die Zeile von früheren Ausgaben frei)

Vergessen Sie auch nicht, mit einem print "" zu beenden, um mindestens einen finalen Newline zu erhalten!

72
mvds

Mit Python 3.x können Sie Folgendes tun:

print('bla bla', end='')

(das auch in Python 2.6 oder 2.7 verwendet werden kann, indem Sie from __future__ import print_function oben in Ihr Skript/Modul einfügen)

Beispiel für die Fortschrittsleiste der Python-Konsole:

import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    n=0
    while n<total:
        done = '#'*(n+1)
        todo = '-'*(total-n-1)
        s = '<{0}>'.format(done+todo)
        if not todo:
            s+='\n'        
        if n>0:
            s = '\r'+s
        print(s, end='')
        yield n
        n+=1

# example for use of status generator
for i in range_with_status(10):
    time.sleep(0.1)
26
Remi

Was für mich funktionierte, war eine Kombination aus Remis und Siriusds Antworten:

from __future__ import print_function
import sys

print(str, end='\r')
sys.stdout.flush()
14
dlchambers

für Konsole wirst du wahrscheinlich brauchen 

sys.stdout.flush()

update erzwingen. Ich denke, dass , in print stdout davon abhält, zu spülen, und irgendwie wird es nicht aktualisiert 

10
siriusd

Niemand hat erwähnt, dass Sie in Python 3 (.something?) sys.stdout.flush() nicht benötigen. print('foobar', end='', flush=True) funktioniert.

2
LeopardShark

Das funktioniert für mich, hat es einmal gehackt, um zu sehen, ob es möglich ist, aber nie in meinem Programm verwendet wurde (GUI ist so viel schöner):

import time
f = '%4i %%'
len_to_clear = len(f)+1
clear = '\x08'* len_to_clear
print 'Progress in percent:'+' '*(len_to_clear),
for i in range(123):
    print clear+f % (i*100//123),
    time.sleep(0.4)
raw_input('\nDone')
2
import time
import sys


def update_pct(w_str):
    w_str = str(w_str)
    sys.stdout.write("\b" * len(w_str))
    sys.stdout.write(" " * len(w_str))
    sys.stdout.write("\b" * len(w_str))
    sys.stdout.write(w_str)
    sys.stdout.flush()

for pct in range(0, 101):
    update_pct("{n}%".format(n=str(pct)))
    time.sleep(0.1)

\b verschiebt die Position des Cursors um ein Leerzeichen zurück
Wir bewegen es also bis zum Anfang der Zeile zurück
Wir schreiben dann Leerzeichen, um die aktuelle Zeile zu löschen - während wir Leerzeichen schreiben, bewegt sich der Cursor um eins nach vorne/rechts
Dann müssen wir den Cursor am Anfang der Zeile zurückbewegen, bevor wir unsere neuen Daten schreiben 

Getestet unter Windows cmd mit Python 2.7

2
Robert

Versuchen Sie es so:

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete",

(Mit einem Komma am Ende.)

1
chryss

Basierend auf Remi answer für Python 2.7+ verwenden Sie Folgendes:

from __future__ import print_function
import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    import sys
    n = 0
    while n < total:
        done = '#' * (n + 1)
        todo = '-' * (total - n - 1)
        s = '<{0}>'.format(done + todo)
        if not todo:
            s += '\n'
        if n > 0:
            s = '\r' + s
        print(s, end='\r')
        sys.stdout.flush()
        yield n
        n += 1


# example for use of status generator
for i in range_with_status(50):
    time.sleep(0.2)

Für Python 3.6+ und für jede list anstatt nur für ints sowie für die Verwendung der gesamten Breite Ihres Konsolenfensters und ohne Übergang zu einer neuen Zeile können Sie Folgendes verwenden:

hinweis: Bitte beachten Sie, dass die Funktion get_console_with() nur auf Linux-basierten Systemen funktioniert und Sie sie daher neu schreiben müssen, damit sie unter Windows funktioniert.

import os
import time

def get_console_width():
    """Returns the width of console.

    NOTE: The below implementation works only on Linux-based operating systems.
    If you wish to use it on another OS, please make sure to modify it appropriately.
    """
    return int(os.popen('stty size', 'r').read().split()[1])


def range_with_progress(list_of_elements):
    """Iterate through list with a progress bar shown in console."""

    # Get the total number of elements of the given list.
    total = len(list_of_elements)
    # Get the width of currently used console. Subtract 2 from the value for the
    # Edge characters "[" and "]"
    max_width = get_console_width() - 2
    # Start iterating over the list.
    for index, element in enumerate(list_of_elements):
        # Compute how many characters should be printed as "done". It is simply
        # a percentage of work done multiplied by the width of the console. That
        # is: if we're on element 50 out of 100, that means we're 50% done, or
        # 0.5, and we should mark half of the entire console as "done".
        done = int(index / total * max_width)
        # Whatever is left, should be printed as "unfinished"
        remaining = max_width - done
        # Print to the console.
        print(f'[{done * "#"}{remaining * "."}]', end='\r')
        # yield the element to work with it
        yield element
    # Finally, print the full line. If you wish, you can also print whitespace
    # so that the progress bar disappears once you are done. In that case do not
    # forget to add the "end" parameter to print function.
    print(f'[{max_width * "#"}]')


if __== '__main__':
    list_of_elements = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    for e in range_with_progress(list_of_elements):
        time.sleep(0.2)

0
tamaroth