367 Stimmen

Dynamischer Druck in einer Zeile

Ich möchte mehrere Anweisungen erstellen, die eine Standardausgabe erzeugen, ohne dass zwischen den Anweisungen Zeilenumbrüche auftreten.

Konkret: Nehmen wir an, ich habe:

for item in range(1,100):
    print item

Das Ergebnis ist:

1
2
3
4
.
.
.

Wie kann dies stattdessen aussehen?

1 2 3 4 5 ...

Noch besser: Ist es möglich, die einzelne Nummer zu drucken über die letzte Zahl, so dass immer nur eine Zahl auf dem Bildschirm zu sehen ist?

553voto

ewall Punkte 25613

Ändern Sie print item zu:

  • print item, in Python 2.7
  • print(item, end=" ") in Python 3

Wenn Sie die Daten dynamisch drucken wollen, verwenden Sie folgende Syntax:

  • print(item, sep=' ', end='', flush=True) in Python 3

172voto

zwol Punkte 128461

Übrigens...... Wie kann man sie jedes Mal aktualisieren, damit sie an einem Ort gedruckt wird, indem man die Nummer ändert.

Im Allgemeinen geschieht dies mit Terminal-Steuercodes . Dies ist ein besonders einfacher Fall, für den Sie nur ein Sonderzeichen benötigen: U+000D CARRIAGE RETURN, das geschrieben wird '\r' in Python (und vielen anderen Sprachen). Hier ist ein vollständiges Beispiel, das auf Ihrem Code basiert:

from sys import stdout
from time import sleep
for i in range(1,20):
    stdout.write("\r%d" % i)
    stdout.flush()
    sleep(1)
stdout.write("\n") # move the cursor to the next line

Einige Dinge, die vielleicht überraschend sind:

  • En \r wird an den Anfang der Zeichenkette gesetzt, so dass sich der Cursor während der Ausführung des Programms immer hinter der Zahl befindet. Das ist nicht nur kosmetisch: Einige Terminal-Emulatoren sind sehr verwirrt, wenn Sie es andersherum machen.
  • Wenn Sie die letzte Zeile nicht einfügen, wird Ihre Shell nach der Beendigung des Programms ihren Prompt über der Zahl ausgeben.
  • En stdout.flush ist auf einigen Systemen notwendig, sonst erhalten Sie keine Ausgabe. Bei anderen Systemen ist dies vielleicht nicht erforderlich, aber es schadet nicht.

Wenn Sie feststellen, dass dies nicht funktioniert, sollten Sie als erstes vermuten, dass Ihr Terminalemulator fehlerhaft ist. Der vttest Programm kann Ihnen beim Testen helfen.

Sie könnten die stdout.write mit einer print Aussage, aber ich ziehe es vor, nicht zu mischen print mit direkter Verwendung von Dateiobjekten.

56voto

Tim Pietzcker Punkte 311448

Verwenden Sie print item, um den Zeilenumbruch in der Druckanweisung wegzulassen.

In Python 3 heißt es print(item, end=" ") .

Wenn Sie möchten, dass alle Zahlen an der gleichen Stelle angezeigt werden, verwenden Sie zum Beispiel (Python 2.7):

to = 20
digits = len(str(to - 1))
delete = "\b" * (digits + 1)
for i in range(to):
    print "{0}{1:{2}}".format(delete, i, digits),

In Python 3 ist es ein bisschen komplizierter; hier müssen Sie flush sys.stdout oder es wird nichts gedruckt, bis die Schleife beendet ist:

import sys
to = 20
digits = len(str(to - 1))
delete = "\b" * (digits)
for i in range(to):
   print("{0}{1:{2}}".format(delete, i, digits), end="")
   sys.stdout.flush()

22voto

Matthew Punkte 696

Wie die anderen Beispiele,
Ich verwende einen ähnlichen Ansatz, aber anstatt Zeit damit zu verbringen, die letzte Ausgabelänge usw. zu berechnen,

Ich verwende einfach ANSI-Code-Escapes, um an den Anfang der Zeile zurückzukehren, und lösche dann die gesamte Zeile, bevor ich meine aktuelle Statusausgabe ausdrucke.

import sys

class Printer():
    """Print things to stdout on one line dynamically"""
    def __init__(self,data):
        sys.stdout.write("\r\x1b[K"+data.__str__())
        sys.stdout.flush()

Zur Verwendung in Ihrer Iterationsschleife würden Sie einfach etwas wie aufrufen:

x = 1
for f in fileList:
    ProcessFile(f)
    output = "File number %d completed." % x
    Printer(output)
    x += 1   

Siehe mehr hier

15voto

Hugh Perkins Punkte 7016

So viele komplizierte Antworten. Wenn Sie Python 3 haben, setzen Sie einfach \r am Anfang des Ausdrucks, und fügen Sie end='', flush=True dazu:

import time

for i in range(10):
    print(f'\r{i} foo bar', end='', flush=True)
    time.sleep(0.5)

Damit wird geschrieben 0 foo bar dann 1 foo bar usw., an Ort und Stelle.

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