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?

16voto

Gummbum Punkte 141

Das Folgende funktioniert in Python 2.6, 2.7 und 3.2:

import os
import sys
buf_arg = 0
if sys.version_info[0] == 3:
    os.environ['PYTHONUNBUFFERED'] = '1'
    buf_arg = 1
sys.stdout = os.fdopen(sys.stdout.fileno(), 'a+', buf_arg)
sys.stderr = os.fdopen(sys.stderr.fileno(), 'a+', buf_arg)

15voto

Mark Seaborn Punkte 1272
def disable_stdout_buffering():
    # Appending to gc.garbage is a way to stop an object from being
    # destroyed.  If the old sys.stdout is ever collected, it will
    # close() stdout, which is not good.
    gc.garbage.append(sys.stdout)
    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

# Then this will give output in the correct order:
disable_stdout_buffering()
print "hello"
subprocess.call(["echo", "bye"])

Ohne die alte sys.stdout zu speichern, ist disable_stdout_buffering() nicht idempotent, und mehrere Aufrufe führen zu einem Fehler wie diesem:

Traceback (most recent call last):
  File "test/buffering.py", line 17, in <module>
    print "hello"
IOError: [Errno 9] Bad file descriptor
close failed: [Errno 9] Bad file descriptor

Eine andere Möglichkeit ist:

def disable_stdout_buffering():
    fileno = sys.stdout.fileno()
    temp_fd = os.dup(fileno)
    sys.stdout.close()
    os.dup2(temp_fd, fileno)
    os.close(temp_fd)
    sys.stdout = os.fdopen(fileno, "w", 0)

(Das Anhängen an gc.garbage ist keine so gute Idee, weil dort unfreie Zyklen abgelegt werden, die Sie vielleicht überprüfen wollen).

15voto

Oliver Punkte 24156

In Python 3 kann man die Druckfunktion so umprogrammieren, dass sie immer flush=True sendet:

_orig_print = print

def print(*args, **kwargs):
    _orig_print(*args, flush=True, **kwargs)

Wie in einem Kommentar erwähnt, können Sie dies vereinfachen, indem Sie den Flush-Parameter an einen Wert binden, und zwar über functools.partial :

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

13voto

Nathan Punkte 11264

Ja, sie ist standardmäßig aktiviert. Sie können sie deaktivieren, indem Sie beim Aufruf von Python die Option -u in der Befehlszeile verwenden.

8voto

dyomas Punkte 670

Sie können Python auch mit stdbuf Nutzen:

stdbuf -oL python <script>

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