Erhöhen Sie die Standardpuffergröße von Python

Nov 26 2020

Gibt es eine Möglichkeit, die stdoutPuffergröße von 8182 in Python zu erhöhen oder den Flush zu verzögern, bis ich tatsächlich aufrufe flush?

Dinge, die ich ausprobiert habe und die nicht funktionieren:

  • Ich kann dieses Problem unter Windows umgehen, da ich direkt auf den Puffer zugreifen kann ( siehe z. B. meine Antwort auf diesen Beitrag ). Dies funktioniert jedoch nicht unter Unix.
  • Ich kann die Puffergröße für eine Datei erhöhen, indem ich sie bufferan den Konstruktor übergebe, sie ist jedoch stdoutbereits erstellt.
  • Das Ausschalten von buffering ( python -u) macht die Sache offensichtlich noch schlimmer!
  • Bei Verwendung eines temporären Puffers stdouttreten dieselben Probleme auf - wird gelöscht, nachdem jedes 8192. Byte aus dem temporären Puffer kopiert wurde.

Begründung: Ziel ist es, das Flackern der Konsole zu reduzieren. Alles zu puffern, wie in dieser Frage beschrieben, funktioniert tatsächlich, zum Beispiel, wenn ich es in C versuche oder die Windows-API in Python verwende, aber das 8182-Limit in Python scheint Probleme zu verursachen, die ich unter Unix nicht umgehen kann.

Antworten

1 blhsing Nov 27 2020 at 05:29

Sie können den als verfügbar verfügbaren unformatierten Standard-Stream sys.stdout.buffermit einer größeren Puffergröße umschließen io.BufferedWriterund dann den resultierenden gepufferten Binär-Stream als gepufferten Text-Stream umschließen mit io.TextIOWrapper:

import io
import sys

sys.stdout = io.TextIOWrapper(io.BufferedWriter(sys.stdout.buffer, new_size))

Hier ist eine Demonstration des Effekts der Erhöhung der Puffergröße von stdout auf 100000, sodass die beiden Druckausgaben mit einer Länge von 10000 Zeichen erst gelöscht werden, wenn eine manuelle Leerung aufgerufen wird:

import io
import sys
import time

print('Original buffer size:', io.DEFAULT_BUFFER_SIZE)
for large_buffer in False, True:
    if large_buffer:
        print('Increasing buffer size...')
        sys.stdout = io.TextIOWrapper(io.BufferedWriter(sys.stdout.buffer, 100000))
    for i in range(2):
        time.sleep(2)
        print(str(i * 2) * 10000)
        time.sleep(2)
        print(str(i * 2 + 1) *10000)
        print(f'Flush #{i + 1}')
        sys.stdout.flush()

Demo: https://repl.it/@blhsing/UnkemptGullibleDecompiler

1 cz Nov 27 2020 at 16:39

Fand die Antwort eigentlich sehr einfach:

my_stdout = open( 1, "w", buffering = 100000 )
  • 1ist das filenofür stdout.
  • sys.stdout = my_stdoutkann verwendet werden, um die Änderung am Standardziel vorzunehmen print.
  • Ich habe dies nur unter Unix getestet.