Wie Ausgabe von Druckfunktion spülen?
-
04-07-2019 - |
Frage
Wie erzwinge ich Python der Druckfunktion für die Ausgabe auf den Bildschirm?
Dies ist kein Duplikat deaktivieren Ausgabepufferung - die verknüpfte Frage versucht ungepufferte Ausgabe, während diese allgemeinere ist. Die Top-Antworten in dieser Frage sind zu mächtig oder Beteiligten für diesen (sie dafür nicht gute Antworten sind), und diese Frage kann durch einen relativen Neuling auf Google gefunden werden.
Lösung
import sys
sys.stdout.flush()
print
standardmäßig druckt sys.stdout
.
Referenzen
Python 2
Python 3
-
print()
-
sys.stdout
- Dateiobjekt - Glossar
-
io.IOBase.flush()
(sys.stdout
erbt dieflush
Methode ausio.IOBase
)
Andere Tipps
Beim Laufen python -h
sehe ich eine Befehlszeilenoption :
-u: ungepufferte binärer stdout und stderr; auch x PYTHONUNBUFFERED = siehe Manpage für Details über interne Pufferung in Zusammenhang mit ‚-u‘
Hier ist der rel="noreferrer">.
Seit Python 3.3 können Sie die normale Funktion print()
erzwingen, ohne die Notwendigkeit zu spülen sys.stdout.flush()
zu verwenden; das "flush" Keyword-Argument auf true gerade eingestellt hat. Aus der Dokumentation :
print (* Objekte, sep =‘‘, end = '\ n', file = sys.stdout, bündig = False)
Druck Objekte in die Stream-Datei, getrennt durch September und anschließend Ende. September, Ende und Datei, falls vorhanden, muss als Keyword-Argumente angegeben werden.
Alle Nicht-Schlüsselwort-Argumente umgewandelt werden, um Strings wie str () tut und in den Stream geschrieben, von September getrennt und von Ende gefolgt. Sowohl September und Ende müssen Strings sein; sie können auch keine sein, die die Standardwerte zu verwenden bedeutet. Wenn keine Objekte angegeben sind, print () wird nur Ende schreiben.
Die Datei Argument muss ein Objekt mit einer Schreib (string) Methode; wenn es nicht vorhanden ist oder keine ist, wird sys.stdout verwendet werden. Ob Ausgang gepuffert wird in der Regel durch Datei bestimmt, aber wenn das flush Schlüsselwort-Argument wahr ist, ist der Strom gewaltsam gespült.
Wie Ausgabe von Python Druck spülen?
Ich schlage vor, fünf Möglichkeiten, dies zu tun:
- In Python 3, Call
print(..., flush=True)
(das flush Argument ist nicht verfügbar Druckfunktion des Python 2, und es gibt nicht analog für die print-Anweisung). - Anruf
file.flush()
auf der Ausgabedatei (wir können Python 2 der Druckfunktion wickeln, dies zu tun), zum Beispiel,sys.stdout
- dies auf jeden Druckfunktionsaufruf in dem Modul mit einer Teilfunktion,
print = partial(print, flush=True)
an das Modul angelegt global. - dies auf den Prozess mit einem Flag (
-u
) an den Interpreter-Befehl übergeben - dies auf jeden Python-Prozess in Ihrer Umgebung mit
PYTHONUNBUFFERED=TRUE
(und unset die Variable dies rückgängig zu machen).
Python 3.3 +
Mit Python 3.3 oder höher, können Sie einfach flush=True
als Schlüsselwort Argument für die print
Funktion bieten:
print('foo', flush=True)
Python 2 (oder <3.3)
Sie haben nicht zurückzuportieren das flush
Argument zu Python 2.7 Also, wenn Sie mit Python 2 (oder weniger als 3,3) und Code mögen, die beide mit 2 kompatibel sind und 3 kann ich den folgenden Kompatibilitätscode vorschlagen. (Beachten Sie die __future__
Import bei / sehr „in der Nähe des oben in Ihrem Modul sein muss "):
from __future__ import print_function
import sys
if sys.version_info[:2] < (3, 3):
old_print = print
def print(*args, **kwargs):
flush = kwargs.pop('flush', False)
old_print(*args, **kwargs)
if flush:
file = kwargs.get('file', sys.stdout)
# Why might file=None? IDK, but it works for print(i, file=None)
file.flush() if file is not None else sys.stdout.flush()
Der obige Kompatibilitätscode wird die meisten Anwendungen abdecken, aber für eine viel gründlichere Behandlung, siehe six
Modul .
Alternativ können Sie nur file.flush()
nach dem Druck nennen, beispielsweise mit der print-Anweisung in Python 2:
import sys
print 'delayed output'
sys.stdout.flush()
Ändern des Standard in einem Modul zum flush=True
Sie können die Standardeinstellung für die Druckfunktion ändern, indem Sie auf den globalen Bereich eines Moduls mit functools.partial:
import functools
print = functools.partial(print, flush=True)
Wenn Sie einen Blick auf unsere neuen Teilfunktion, zumindest in Python 3:
>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)
Wir können sehen, es funktioniert wie normal:
>>> print('foo')
foo
Und wir können den neuen Standard tatsächlich außer Kraft setzen:
>>> print('foo', flush=False)
foo
Hinweis wieder, dies ändert sich nur die aktuellen globalen Umfang, da der Druckname auf dem aktuellen globalen Bereich wird die eingebaute print
Funktion (oder dereferenzieren die Kompatibilität Funktion, wenn unter Verwendung von Python 2, in diesem aktuellen globalen Bereich) beschatten.
Wenn Sie dies innerhalb einer Funktion tun wollen, anstatt auf einem globalen Bereich des Moduls, sollten Sie ihm einen anderen Namen geben, z.
def foo():
printf = functools.partial(print, flush=True)
printf('print stuff like this')
Wenn Sie es eine globale in einer Funktion deklarieren, sind Sie auf das Modul der globalen Namensraum zu ändern, so sollten Sie es nur in dem globalen Namensraum setzen, es sei denn, dass ein bestimmtes Verhalten ist genau das, was Sie wollen.
Ändern der Standardeinstellung für den Prozess
Ich denke, die beste Option ist hier die -u
Flag verwenden ungepufferte Ausgabe zu erhalten.
$ python -u script.py
oder
$ python -um package.module
Von der docs :
Kraft stdin, stdout und stderr als völlig ungepufferte. Auf Systemen, bei denen es darauf ankommt, setzen auch stdin, stdout und stderr im Binär-Modus.
Beachten Sie, dass es interne Pufferung in file.readlines () und Dateiobjekten (für Zeile in sys.stdin), die von dieser Option nicht beeinflusst wird. Um dies zu umgehen, werden Sie file.readline () innerhalb einer Weile 1 verwenden. Schleife
Ändern der Standardeinstellung für die Shell-Betriebsumgebung
Sie können dieses Verhalten für alle Python-Prozesse in der Umwelt oder in Umgebungen erhalten, die von der Umwelt erbt, wenn Sie die Umgebungsvariable auf einen nicht leeren stri gesetztng:
z, in Linux oder OSX.
$ export PYTHONUNBUFFERED=TRUE
oder Windows:
C:\SET PYTHONUNBUFFERED=TRUE
von der docs :
PYTHONUNBUFFERED
Wenn dies auf eine nicht leere Zeichenfolge festgelegt ist äquivalent ist, die Option -u angeben.
Nachtrag
Hier ist die Hilfe auf der Druckfunktion von Python 2.7.12 - beachten Sie, dass es nicht flush
Argument:
>>> from __future__ import print_function
>>> help(print)
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
Mit Python 3.x die print()
Funktion erweitert:
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
Also, Sie können einfach tun:
print("Visiting toilet", flush=True)
Mit dem -u
Befehlszeilenschalter funktioniert, aber es ist ein wenig unbeholfen. Es würde bedeuten, dass das Programm würde möglicherweise falsch verhalten, wenn der Benutzer das Skript ohne die -u
Option aufgerufen. Normalerweise verwende ich eine benutzerdefinierte stdout
, wie folgt aus:
class flushfile:
def __init__(self, f):
self.f = f
def write(self, x):
self.f.write(x)
self.f.flush()
import sys
sys.stdout = flushfile(sys.stdout)
... Jetzt sind alle Ihre print
Anrufe (die sys.stdout
implizit verwenden), wird automatisch flush
ed werden.
Warum nicht versuchen, eine ungepufferte Datei mit?
f = open('xyz.log', 'a', 0)
oder
sys.stdout = open('out.log', 'a', 0)
Dans Idee funktioniert nicht ganz:
#!/usr/bin/env python
class flushfile(file):
def __init__(self, f):
self.f = f
def write(self, x):
self.f.write(x)
self.f.flush()
import sys
sys.stdout = flushfile(sys.stdout)
print "foo"
Das Ergebnis:
Traceback (most recent call last):
File "./passpersist.py", line 12, in <module>
print "foo"
ValueError: I/O operation on closed file
Ich glaube, das Problem ist, dass es aus der Datei-Klasse erbt, die eigentlich nicht notwendig ist. Nach der Dokumentation für sys.stdout:
stdout und stderr braucht nicht eingebaut zu werden Dateiobjekte: jedes Objekt akzeptabel solange es eine write () Methode hat das braucht ein String-Argument.
so zu ändern
class flushfile(file):
class flushfile(object):
macht es gut funktionieren.
Hier ist meine Version, die writelines () und fileno () auch sieht vor:
class FlushFile(object):
def __init__(self, fd):
self.fd = fd
def write(self, x):
ret = self.fd.write(x)
self.fd.flush()
return ret
def writelines(self, lines):
ret = self.writelines(lines)
self.fd.flush()
return ret
def flush(self):
return self.fd.flush
def close(self):
return self.fd.close()
def fileno(self):
return self.fd.fileno()
In Python 3 Sie Druckfunktion mit Standardsatz überschreiben können flush = True
def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
__builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)
Ich habe es so in Python 3.4:
'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')