Augmenter la taille du tampon stdout de Python
Existe-t-il un moyen d'augmenter la stdout
taille 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
buffer
au constructeur, mais ilstdout
est 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 -
stdout
est 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
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
J'ai trouvé la réponse, en fait très simple:
my_stdout = open( 1, "w", buffering = 100000 )
1
est lefileno
pourstdout
.sys.stdout = my_stdout
peut être utilisé pour modifier laprint
cible par défaut .- Je n'ai testé cela que sur Unix.