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?

3voto

cji Punkte 6426

"Übrigens...... Wie kann man es jedes Mal aktualisieren, damit es an einer Stelle gedruckt wird, indem man einfach die Nummer ändert."

Das ist ein wirklich heikles Thema. Was zack (Ausgabe von Konsolensteuercodes) ist eine Möglichkeit, dies zu erreichen.

Sie können (n)curses verwenden, aber das funktioniert hauptsächlich auf *nixes.

Unter Windows (und hier kommt der interessante Teil), der selten erwähnt wird (ich kann nicht verstehen, warum), können Sie Python-Bindungen an WinAPI verwenden ( http://sourceforge.net/projects/pywin32/ auch mit ActivePython standardmäßig) - es ist nicht so schwer und funktioniert gut. Hier ist ein kleines Beispiel:

import win32console, time

output_handle = win32console.GetStdHandle(  win32console.STD_OUTPUT_HANDLE )
info = output_handle.GetConsoleScreenBufferInfo()
pos = info["CursorPosition"]

for i in "\\|/-\\|/-":
    output_handle.WriteConsoleOutputCharacter( i, pos )
    time.sleep( 1 )

Oder, wenn Sie Folgendes verwenden möchten print (Anweisung oder Funktion, kein Unterschied):

import win32console, time

output_handle = win32console.GetStdHandle(  win32console.STD_OUTPUT_HANDLE )
info = output_handle.GetConsoleScreenBufferInfo()
pos = info["CursorPosition"]

for i in "\\|/-\\|/-":
    print i
    output_handle.SetConsoleCursorPosition( pos )
    time.sleep( 1 )

win32console Modul ermöglicht es Ihnen, viele weitere interessante Dinge mit der Windows-Konsole zu tun... Ich bin kein großer Fan von WinAPI, aber vor kurzem habe ich erkannt, dass mindestens die Hälfte meiner Abneigung dagegen durch das Schreiben von WinAPI-Code in C verursacht wurde - pythonische Bindungen sind viel einfacher zu verwenden.

Alle anderen Antworten sind natürlich toll und pythonisch, aber... Was wäre, wenn ich drucken wollte auf vorherige Linie? Oder einen mehrzeiligen Text schreiben, ihn dann löschen und dieselben Zeilen erneut schreiben? Meine Lösung macht das möglich.

2voto

Luiz Martins Punkte 1493

Hinweis: Ich weise auf diese Lösung hin, weil die meisten anderen, die ich gesehen habe, nicht funktionieren, wenn die Länge des nächsten Drucks kleiner ist als die des vorherigen.

Wenn Sie wissen, was Sie löschen wollen, und sich eine globale Variable leisten können, können Sie die letzte Zeile einfach mit Leerzeichen überschreiben.

  1. Speichern Sie vor dem Drucken die Länge der Zeichenkette als 'n'.
  2. Drucken Sie es aus, aber enden Sie mit ' \r ' (er kehrt an den Anfang der Zeile zurück).
  3. Beim nächsten Mal drucken Sie vor dem Ausdrucken Ihrer Nachricht 'n' Leerzeichen über die Zeile.

    _last_print_len = 0 def reprint(msg, finish=False): global _last_print_len

    # Ovewrites line with spaces.
    print(' '*_last_print_len, end='\r')
    
    if finish:
        end = '\n'
        # If we're finishing the line, we won't need to overwrite it in the next print.
        _last_print_len = 0
    else:
        end = '\r'
        # Store len for the next print.
        _last_print_len = len(msg)
    
    # Printing message.
    print(msg, end=end)

Beispiele:

for i in range(10):
    reprint('Loading.')
    time.sleep(1)
    reprint('Loading..')
    time.sleep(1)
    reprint('Loading...')
    time.sleep(1)

enter image description here

for i in range(10):
    reprint('Loading.')
    time.sleep(1)
    reprint('Loading..')
    time.sleep(1)
    reprint('Loading...', finish=True)
    time.sleep(1)

enter image description here

2voto

Oder noch einfacher:

import time
a = 0
while True:
    print (a, end="\r")
    a += 1
    time.sleep(0.1)

end="\r" überschreibt vom Anfang [0:] des ersten Ausdrucks an.

2voto

Structure Punkte 822

Für diejenigen, die kämpfen, wie ich es tat, kam ich mit der folgenden, die sowohl in Python 3.7.4 und 3.5.2 zu arbeiten scheint.

Ich habe den Bereich von 100 bis 1.000.000 erweitert, weil er sehr schnell abläuft und Sie die Ausgabe möglicherweise nicht sehen. Dies liegt daran, dass ein Nebeneffekt der Einstellung end='\r' ist, dass die letzte Schleifeniteration die gesamte Ausgabe löscht. Um zu zeigen, dass es funktioniert, war eine längere Zahl erforderlich. Dieses Ergebnis ist vielleicht nicht in allen Fällen wünschenswert, aber in meinem Fall war es in Ordnung, und der Auftraggeber hat sich nicht auf eine bestimmte Weise festgelegt. Sie könnten dies möglicherweise mit einer if-Anweisung umgehen, die die Länge des Arrays auswertet, über das iteriert wird, usw. Der Schlüssel, damit es in meinem Fall funktioniert, war, die Klammern "{}" mit .format() . Ansonsten hat es nicht funktioniert.

Das Folgende sollte so funktionieren, wie es ist:

#!/usr/bin/env python3

for item in range(1,1000000):
    print("{}".format(item), end='\r', flush=True)

2voto

Stryker Punkte 5104

In Python 3 können Sie dies auf diese Weise tun:

for item in range(1,10):
    print(item, end =" ")

Ausgänge:

1 2 3 4 5 6 7 8 9 

Tupel: Sie können dasselbe mit einem Tupel tun:

tup = (1,2,3,4,5)

for n in tup:
    print(n, end = " - ")

Ausgänge:

1 - 2 - 3 - 4 - 5 - 

Ein weiteres Beispiel:

list_of_tuples = [(1,2),('A','B'), (3,4), ('Cat', 'Dog')]
for item in list_of_tuples:
    print(item)

Ausgänge:

(1, 2)
('A', 'B')
(3, 4)
('Cat', 'Dog')

Sie können Ihr Tupel sogar wie folgt entpacken:

list_of_tuples = [(1,2),('A','B'), (3,4), ('Cat', 'Dog')]

# Tuple unpacking so that you can deal with elements inside of the tuple individually
for (item1, item2) in list_of_tuples:
    print(item1, item2)   

Ausgänge:

1 2
A B
3 4
Cat Dog

eine andere Variante:

list_of_tuples = [(1,2),('A','B'), (3,4), ('Cat', 'Dog')]
for (item1, item2) in list_of_tuples:
    print(item1)
    print(item2)
    print('\n')

Ausgänge:

1
2

A
B

3
4

Cat
Dog

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