Augmenter la taille du tampon stdout de Python

Nov 26 2020

Existe-t-il un moyen d'augmenter la stdouttaille du tampon de 8182 en Python ou de retarder le vidage jusqu'à ce que j'appelle réellement flush?

Les choses que j'ai essayées qui ne fonctionnent pas:

  • Je peux contourner ce problème sous Windows car je peux accéder directement au tampon (par exemple, voir ma réponse à ce post ). Mais cela ne fonctionne pas pour Unix.
  • Je peux augmenter la taille du tampon pour un fichier en passant bufferau constructeur, mais il stdoutest déjà construit.
  • La désactivation de la mise en mémoire tampon ( python -u) aggrave évidemment les choses!
  • L'utilisation d'un tampon temporaire rencontre les mêmes problèmes - stdoutest vidé après chaque 8192 octet est copié à partir du tampon temporaire.

Justification: Le but ici est de réduire le scintillement de la console. La mise en mémoire tampon de tout, selon cette question fonctionne en effet, par exemple lorsque j'essaye en C ou en utilisant l'API Windows en Python, mais la limite de 8182 en Python semble causer des problèmes que je ne peux pas contourner sous Unix.

Réponses

1 blhsing Nov 27 2020 at 05:29

Vous pouvez encapsuler le flux stdout brut, disponible sous forme de sys.stdout.buffer, avec une taille de tampon plus grande avec io.BufferedWriter, puis encapsuler le flux binaire tamponné résultant en tant que flux de texte tamponné avec io.TextIOWrapper:

import io
import sys

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

Voici une démonstration de l'effet de l'augmentation de la taille de la mémoire tampon de stdout à 100000 afin qu'il ne vide pas les deux sorties d'impression de 10000 caractères jusqu'à ce qu'un vidage manuel soit appelé:

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

Démo: https://repl.it/@blhsing/UnkemptGullibleDecompiler

1 cz Nov 27 2020 at 16:39

J'ai trouvé la réponse, en fait très simple:

my_stdout = open( 1, "w", buffering = 100000 )
  • 1est le filenopour stdout.
  • sys.stdout = my_stdoutpeut être utilisé pour modifier la printcible par défaut .
  • Je n'ai testé cela que sur Unix.