Gibt es Situationen, in denen sys.stdout.write()
print
vorzuziehen ist?
(Beispiele: bessere Leistung; sinnvollerer Code)
print
ist nur ein dünner Wrapper, der die Eingaben formatiert (änderbar, aber standardmäßig mit einem Leerzeichen zwischen args und newline am Ende) und die Schreibfunktion eines bestimmten Objekts aufruft. Standardmäßig ist dieses Objekt sys.stdout
, aber Sie können eine Datei mit dem "Chevron" -Formular übergeben. Zum Beispiel:
print >> open('file.txt', 'w'), 'Hello', 'World', 2+3
Siehe: https://docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement
In Python 3.x wird print
zu einer Funktion, aber es ist immer noch möglich, etwas anderes als sys.stdout
zu übergeben, dank dem file
argument.
print('Hello', 'World', 2+3, file=open('file.txt', 'w'))
Siehe https://docs.python.org/3/library/functions.html#print
In Python 2.6+ ist print
immer noch eine Anweisung, sie kann jedoch als Funktion mit verwendet werden
from __future__ import print_function
Update: Bakuriu kommentierte, dass es einen kleinen Unterschied zwischen der Druckfunktion und der Druckanweisung (und allgemeiner zwischen einer Funktion und einer Anweisung) gibt.
Im Falle eines Fehlers bei der Auswertung der Argumente:
print "something", 1/0, "other" #prints only something because 1/0 raise an Exception
print("something", 1/0, "other") #doesn't print anything. The function is not called
print
konvertiert zuerst das Objekt in eine Zeichenfolge (falls es noch keine Zeichenfolge ist). Es wird auch ein Leerzeichen vor dem Objekt eingefügt, wenn es nicht der Anfang einer Zeile und ein Zeilenumbruchzeichen am Ende ist.
Wenn Sie stdout
verwenden, müssen Sie das Objekt selbst in einen String konvertieren (z. B. durch Aufrufen von "str"), und es gibt kein Zeilenumbruchzeichen.
Damit
print 99
ist äquivalent zu:
import sys
sys.stdout.write(str(99) + '\n')
Meine Frage ist, ob es Situationen gibt, in denen
sys.stdout.write()
Nachdem ich neulich mit der Entwicklung eines Skripts fertig war, habe ich es auf einen Unix-Server hochgeladen. Alle meine Debug-Meldungen verwendeten print
Anweisungen, und diese nicht werden in einem Serverprotokoll angezeigt.
In diesem Fall benötigen Sie möglicherweise stattdessen sys.stdout.write
.
Hier ist ein Beispielcode, der auf dem Buch Learning Python von Mark Lutz basiert und Ihre Frage beantwortet:
import sys
temp = sys.stdout # store original stdout object for later
sys.stdout = open('log.txt', 'w') # redirect all prints to this log file
print("testing123") # nothing appears at interactive Prompt
print("another line") # again nothing appears. it's written to log file instead
sys.stdout.close() # ordinary file object
sys.stdout = temp # restore print commands to interactive Prompt
print("back to normal") # this shows up in the interactive Prompt
Wenn Sie log.txt in einem Texteditor öffnen, wird Folgendes angezeigt:
testing123
another line
Es gibt mindestens eine Situation, in der Sie sys.stdout
anstatt drucken möchten.
Wenn Sie eine Zeile überschreiben möchten, ohne zur nächsten zu wechseln, z. B. während Sie einen Fortschrittsbalken oder eine Statusmeldung zeichnen, müssen Sie eine Schleife ausführen
Note carriage return-> "\rMy Status Message: %s" % progress
Und da print eine neue Zeile hinzufügt, ist es besser, sys.stdout
zu verwenden.
Meine Frage ist, ob es Situationen gibt, in denen
sys.stdout.write()
Wenn Sie eine Befehlszeilenanwendung schreiben, die sowohl in Dateien als auch in stdout schreiben kann, ist dies praktisch. Sie können Dinge tun wie:
def myfunc(outfile=None):
if outfile is None:
out = sys.stdout
else:
out = open(outfile, 'w')
try:
# do some stuff
out.write(mytext + '\n')
# ...
finally:
if outfile is not None:
out.close()
Es bedeutet, dass Sie das Muster with open(outfile, 'w') as out:
nicht verwenden können, aber manchmal lohnt es sich.
In 2.x verarbeitet die print
-Anweisung die von Ihnen eingegebenen Daten vor, wandelt sie auf dem Weg in Zeichenfolgen um, verarbeitet Trennzeichen und Zeilenumbrüche und ermöglicht die Umleitung in eine Datei. 3.x verwandelt es in eine Funktion, hat aber immer noch die gleichen Verantwortlichkeiten.
sys.stdout
ist eine Datei oder dateiähnliche Datei, in die Methoden zum Schreiben von Zeichenfolgen oder Ähnlichem geschrieben werden.
Gibt es Situationen, in denen sys.stdout.write () vorzuziehen ist, um zu drucken?
Ich habe festgestellt, dass stdout in einer Multithreading-Situation besser funktioniert als Drucken. Ich verwende die Warteschlange (FIFO), um die zu druckenden Zeilen zu speichern, und halte alle Fäden vor der Druckzeile, bis mein Druck Q leer ist. Trotzdem verliere ich beim Drucken manchmal das letzte\n bei der Debug-E/A (mit Wing Pro IDE).
Wenn ich std.out mit\n in der Zeichenfolge verwende, werden die Debug-E/A-Formate korrekt und die\n korrekt angezeigt.
Gibt es Situationen, in denen sys.stdout.write () vorzuziehen ist, um zu drucken?
Zum Beispiel arbeite ich an einer kleinen Funktion, die beim Übergeben der Zahl als Argument Sterne im Pyramidenformat ausgibt, obwohl Sie dies mit end = "", um in einer separaten Zeile zu drucken, habe ich sys.stdout.write in Abstimmung mit print , damit dies funktioniert. Um dies näher zu erläutern: stdout.write druckt in derselben Zeile, wobei print den Inhalt immer in einer separaten Zeile ausgibt.
import sys
def printstars(count):
if count >= 1:
i = 1
while (i <= count):
x=0
while(x<i):
sys.stdout.write('*')
x = x+1
print('')
i=i+1
printstars(5)
es ist vorzuziehen, wenn dynamisches Drucken nützlich ist, um beispielsweise Informationen in einem langen Prozess bereitzustellen:
import time, sys
Iterations = 555
for k in range(Iterations+1):
# some code to execute here ...
percentage = k / Iterations
time_msg = "\rRunning Progress at {0:.2%} ".format(percentage)
sys.stdout.write(time_msg)
sys.stdout.flush()
time.sleep(0.01)
In Python 3 gibt es einen gültigen Grund, um sys.stdout.write
zu drucken, aber dieser Grund kann auch in einen Grund umgewandelt werden, stattdessen sys.stdout.write
zu verwenden.
Dies liegt daran, dass print jetzt eine Funktion in Python 3 ist, die Sie überschreiben können. Sie können also print überall in einem einfachen Skript verwenden und entscheiden, welche print-Anweisungen stattdessen in stderr
geschrieben werden müssen. Sie können die Druckfunktion jetzt einfach neu definieren. Sie können die Druckfunktion sogar global ändern, indem Sie sie mit dem integrierten Modul ändern. Natürlich können Sie mit file.write
angeben, um welche Datei es sich handelt, aber beim Überschreiben des Ausdrucks können Sie auch das Zeilentrennzeichen oder das Argumenttrennzeichen neu definieren.
Der andere Weg ist. Vielleicht sind Sie sich absolut sicher, dass Sie an stdout
schreiben, wissen aber auch, dass Sie den Ausdruck in etwas anderes ändern werden. Sie können sich entscheiden, sys.stdout.write
zu verwenden und den Ausdruck für das Fehlerprotokoll oder etwas anderes zu verwenden.
Was Sie verwenden, hängt also davon ab, wie Sie es verwenden möchten. print
ist flexibler, aber das kann ein Grund sein, es zu verwenden und nicht zu verwenden. Stattdessen würde ich mich immer noch für Flexibilität entscheiden und Drucken wählen. Ein weiterer Grund, stattdessen print
zu verwenden, ist Vertrautheit. Jetzt werden mehr Menschen wissen, was Sie mit Drucken meinen, und weniger wissen, sys.stdout.write
.
>>> sys.stdout.write(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected a string or other character buffer object
>>> sys.stdout.write("a")
a>>> sys.stdout.write("a") ; print(1)
a1
Beachten Sie das obige Beispiel:
sys.stdout.write
schreibt kein Objekt ohne Zeichenfolge, aber print
sys.stdout.write
fügt am Ende kein neues Liniensymbol hinzu, print
jedoch
Wenn wir tief tauchen,
sys.stdout
ist ein Dateiobjekt, das für die Ausgabe von print () verwendet werden kann.
wenn das Dateiargument von print()
nicht angegeben ist, wird sys.stdout
verwendet