673 Stimmen

Ausgangspufferung deaktivieren

Ist die Ausgabepufferung in Pythons Interpreter standardmäßig aktiviert für sys.stdout ?

Wenn die Antwort positiv ausfällt, welche Möglichkeiten gibt es, sie zu deaktivieren?

Bisherige Vorschläge:

  1. Verwenden Sie die -u Kommandozeilenschalter
  2. Wickeln sys.stdout in einem Objekt, das nach jedem Schreibvorgang geleert wird
  3. Satz PYTHONUNBUFFERED Umgebungsvariable
  4. sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

Gibt es eine andere Möglichkeit, ein globales Flag in sys / sys.stdout programmatisch während der Ausführung?

522voto

Seb Punkte 15918

Von Antwort von Magnus Lycka auf einer Mailingliste :

Sie können die Pufferung für eine ganze python-Prozesses überspringen, indem Sie "python -u" (oder#!/usr/bin/env python -u usw.) oder durch Setzen der Umgebungsvariablen PYTHONUNBUFFERED.

Sie könnten auch sys.stdout durch einen anderen Stream-ähnlichen Wrapper, der nach jedem Aufruf einen Flush durchführt.

class Unbuffered(object):
   def __init__(self, stream):
       self.stream = stream
   def write(self, data):
       self.stream.write(data)
       self.stream.flush()
   def writelines(self, datas):
       self.stream.writelines(datas)
       self.stream.flush()
   def __getattr__(self, attr):
       return getattr(self.stream, attr)

import sys
sys.stdout = Unbuffered(sys.stdout)
print 'Hello'

232voto

Ich würde meine Antwort lieber in Wie wird die Ausgabe der Druckfunktion gelöscht? oder in Pythons Druckfunktion, die den Puffer leert, wenn sie aufgerufen wird? aber da sie als Duplikate dieses Beitrags markiert wurden (was ich nicht gutheiße), werde ich sie hier beantworten.

Seit Python 3.3 unterstützt print() das Schlüsselwortargument "flush" ( siehe Dokumentation ) :

print('Hello World!', flush=True)

91voto

Federico A. Ramponi Punkte 44697
# reopen stdout file descriptor with write mode
# and 0 as the buffer size (unbuffered)
import io, os, sys
try:
    # Python 3, open as binary, then wrap in a TextIOWrapper with write-through.
    sys.stdout = io.TextIOWrapper(open(sys.stdout.fileno(), 'wb', 0), write_through=True)
    # If flushing on newlines is sufficient, as of 3.7 you can instead just call:
    # sys.stdout.reconfigure(line_buffering=True)
except TypeError:
    # Python 2
    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

Credits: "Sebastian", irgendwo auf der Python-Mailingliste.

74voto

Brian Punkte 112487

Ja, das ist sie.

Sie können es auf der Kommandozeile mit dem Schalter "-u" deaktivieren.

Alternativ könnten Sie .flush() auf sys.stdout bei jedem Schreibvorgang aufrufen (oder mit einem Objekt verpacken, das dies automatisch tut)

42voto

Tim Punkte 613

Dies bezieht sich auf die Antwort von Cristóvão D. Sousa, aber ich konnte mich noch nicht dazu äußern.

Eine unkomplizierte Art der Verwendung der flush Schlüsselwortargument von Python 3 um immer eine ungepufferte Ausgabe haben, ist:

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

danach wird print die Ausgabe immer direkt spülen (außer flush=False gegeben ist).

Beachten Sie, (a) dass dies die Frage nur teilweise beantwortet, da nicht alle Ausgaben umgeleitet werden. Aber ich vermute print ist die gebräuchlichste Methode zur Erstellung von Ausgaben für stdout / stderr in Python, also decken diese 2 Zeilen wahrscheinlich die meisten Anwendungsfälle ab.

Beachten Sie (b), dass es nur in dem Modul/Skript funktioniert, in dem Sie es definiert haben. Dies kann gut sein, wenn man ein Modul schreibt, da es nicht mit dem sys.stdout .

Python 2 bietet nicht die flush Argument, aber man könnte einen Python 3-Typ emulieren print Funktion wie hier beschrieben https://stackoverflow.com/a/27991478/3734258 .

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