web-dev-qa-db-de.com

Wie wird die Ausgabe der Druckfunktion gespült?

Wie erzwinge ich die Ausgabe der Python-Druckfunktion auf dem Bildschirm?

Dies ist kein Duplikat von Ausgabepufferung deaktivieren - Die verknüpfte Frage versucht eine ungepufferte Ausgabe, dies ist jedoch allgemeiner. Die häufigsten Antworten in dieser Frage sind zu mächtig oder zu kompliziert (diesbezüglich sind sie keine guten Antworten), und diese Frage kann von einem Neuling bei Google gefunden werden.

1068
Walter Nissen
_import sys
sys.stdout.flush()
_

print wird standardmäßig auf _sys.stdout_ gedruckt.

Verweise

Python 2

Python 3

1247
CesarB

Wenn Sie python -h ausführen, wird eine Befehlszeilenoption angezeigt :

-u: ungepuffertes binäres stdout und stderr; auch PYTHONUNBUFFERED = x siehe Manpage für Details zur internen Pufferung in Bezug auf '-u'

Hier ist das relevantes Dokument .

326
gimel

Seit Python 3.3 können Sie die normale print() -Funktion zum Flush zwingen, ohne sys.stdout.flush() verwenden zu müssen. Setzen Sie einfach das Schlüsselwortargument "flush" auf "true". Von die Dokumentation :

print (* objects, sep = '', end = '\ n', file = sys.stdout, flush = False)

Objekte in die Stream-Datei drucken, getrennt durch sep und gefolgt von end. sep, end und file müssen, falls vorhanden, als Schlüsselwortargumente angegeben werden.

Alle Argumente, die keine Schlüsselwörter sind, werden wie str () in Zeichenfolgen konvertiert und in den Stream geschrieben, getrennt durch sep und gefolgt von end. Sowohl sep als auch end müssen Zeichenfolgen sein. Sie können auch Keine sein, was bedeutet, dass die Standardwerte verwendet werden. Wenn keine Objekte angegeben sind, schreibt print () nur end.

Das Dateiargument muss ein Objekt mit einer Write-Methode (String-Methode) sein. Ist dies nicht der Fall oder None, wird sys.stdout verwendet. Ob die Ausgabe gepuffert wird, hängt normalerweise von der Datei ab. Wenn das Argument für das Schlüsselwort "flush" jedoch zutrifft, wird der Stream zwangsweise gelöscht.

309
Eugene Sajine

Wie kann ich die Ausgabe von Python print leeren?

Ich schlage fünf Möglichkeiten vor:

  • Rufen Sie in Python 3 print(..., flush=True) auf (das Flush-Argument ist in der Druckfunktion von Python 2 nicht verfügbar, und es gibt kein Analogon für die print-Anweisung).
  • Rufen Sie in der Ausgabedatei file.flush() auf (wir können dazu die Druckfunktion von python 2 umbrechen), z. B. sys.stdout
  • wenden Sie dies auf jeden Druckfunktionsaufruf im Modul mit einer Teilfunktion an.
    print = partial(print, flush=True) wird auf das Modul global angewendet.
  • wenden Sie dies auf den Prozess mit einem Flag (-u) an, das an den Interpreter-Befehl übergeben wird
  • wenden Sie dies auf jeden python -Prozess in Ihrer Umgebung mit PYTHONUNBUFFERED=TRUE an (und deaktivieren Sie die Variable, um dies rückgängig zu machen).

Python 3.3+

Mit Python 3.3 oder höher können Sie flush=True als Schlüsselwortargument für die print -Funktion angeben:

print('foo', flush=True) 

Python 2 (oder <3.3)

Sie haben das Argument flush nicht in Python 2.7 zurückportiert. Wenn Sie also Python 2 (oder weniger als 3.3) verwenden, möchten Sie Code, der sowohl mit 2 als auch kompatibel ist 3, darf ich den folgenden Kompatibilitätscode vorschlagen. (Beachten Sie, dass der __future__ -Import bei/sehr "in der Nähe von 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 deckt die meisten Verwendungszwecke ab, aber für eine gründlichere Behandlung siehe das six -Modul .

Alternativ können Sie nach dem Drucken einfach file.flush() aufrufen, zum Beispiel mit der print-Anweisung in Python 2:

import sys
print 'delayed output'
sys.stdout.flush()

Ändern der Standardeinstellung in einem Modul in flush=True

Sie können die Standardeinstellung für die Druckfunktion ändern, indem Sie functools.partial im globalen Bereich eines Moduls verwenden:

import functools
print = functools.partial(print, flush=True)

wenn Sie sich unsere neue Teilfunktion ansehen, zumindest in Python 3:

>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)

Wir können sehen, dass es wie normal funktioniert:

>>> print('foo')
foo

Und wir können den neuen Standardwert tatsächlich überschreiben:

>>> print('foo', flush=False)
foo

Beachten Sie erneut, dass dies nur den aktuellen globalen Bereich ändert, da der Druckname im aktuellen globalen Bereich die eingebaute Funktion print überschattet (oder die Kompatibilitätsfunktion dereferenziert, wenn Python 2 verwendet wird) aktueller globaler Geltungsbereich).

Wenn Sie dies innerhalb einer Funktion anstelle des globalen Bereichs eines Moduls tun möchten, sollten Sie ihm einen anderen Namen geben, z.

def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')

Wenn Sie es in einer Funktion als global deklarieren, ändern Sie es im globalen Namespace des Moduls. Fügen Sie es daher einfach in den globalen Namespace ein, es sei denn, dieses bestimmte Verhalten entspricht genau Ihren Vorstellungen.

Ändern der Standardeinstellung für den Prozess

Ich denke, die beste Option hier ist die Verwendung des Flags -u, um eine ungepufferte Ausgabe zu erhalten.

$ python -u script.py

oder

$ python -um package.module

Aus dem docs :

Erzwinge, dass stdin, stdout und stderr völlig ungepuffert sind. Versetzen Sie auf Systemen, auf denen es wichtig ist, auch stdin, stdout und stderr in den Binärmodus.

Beachten Sie, dass in file.readlines () und File Objects (für die Zeile in sys.stdin) eine interne Pufferung vorhanden ist, die von dieser Option nicht beeinflusst wird. Um dies zu umgehen, sollten Sie file.readline () in einer while 1: -Schleife verwenden.

Ändern der Standardeinstellung für die Shell-Betriebsumgebung

Sie können dieses Verhalten für alle python Prozesse in der Umgebung oder in Umgebungen, die von der Umgebung erben, erhalten, wenn Sie die Umgebungsvariable auf eine nicht leere Zeichenfolge festlegen:

z. B. unter Linux oder OSX:

$ export PYTHONUNBUFFERED=TRUE

oder Windows:

C:\SET PYTHONUNBUFFERED=TRUE

aus dem docs :

PYTHONUNGEPUFFERT

Wenn dies auf eine nicht leere Zeichenfolge festgelegt ist, entspricht dies der Angabe der Option -u.


Nachtrag

Hier ist die Hilfe zur Druckfunktion von Python 2.7.12 - beachten Sie, dass es kein flush Argument gibt:

>>> 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.
157
Aaron Hall

Auch wie in diesem Blog vorgeschlagen, kann man sys.stdout im ungepufferten Modus wieder öffnen:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

Jede Operation stdout.write und print wird anschließend automatisch gelöscht.

69

Mit Python 3.x wurde die Funktion print() erweitert:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

Sie können also einfach Folgendes tun:

print("Visiting toilet", flush=True)

Python Docs Entry

58
Noah Krasser

Die Verwendung des Befehlszeilenschalters -u funktioniert, ist jedoch etwas umständlich. Dies würde bedeuten, dass sich das Programm möglicherweise falsch verhält, wenn der Benutzer das Skript ohne die Option -u aufruft. Normalerweise verwende ich ein benutzerdefiniertes stdout wie folgt:

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 werden alle Ihre print Anrufe (die sys.stdout implizit verwenden) automatisch flushgeschaltet.

36
Dan Lenski

Warum nicht versuchen, eine ungepufferte Datei zu verwenden?

f = open('xyz.log', 'a', 0)

OR

sys.stdout = open('out.log', 'a', 0)
19
Frank
import sys
print 'This will be output immediately.'
sys.stdout.flush()
15
Dynamic

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 von der Dateiklasse erbt, was eigentlich nicht notwendig ist. In den Dokumenten für sys.stdout heißt es:

stdout und stderr müssen keine eingebauten Dateiobjekte sein: Jedes Objekt ist zulässig, solange es eine write () -Methode hat, die ein String-Argument akzeptiert.

so verändernd

class flushfile(file):

zu

class flushfile(object):

macht es gut funktionieren.

13
Kamil Kisiel

Hier ist meine Version, die auch writelines () und fileno () bereitstellt:

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()
8
guettli

Liebte Dans Lösung! Für python3 mache:

import io,sys
class flushfile:
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()
sys.stdout = flushfile(sys.stdout)
7
Jonas Byström

In Python 3 können Sie die Druckfunktion mit der Standardeinstellung flush = True überschreiben.

def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
    __builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)
5
user263387

Ich habe es in Python 3.4 so gemacht:

'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')
4
kmario23