Увеличьте размер буфера стандартного вывода Python

Nov 26 2020

Есть ли способ увеличить stdoutразмер буфера с 8182 в Python или отложить сброс до тех пор, пока я не позвоню flush?

То, что я пробовал, но не работает:

  • Я могу обойти эту проблему в Windows, потому что у меня есть прямой доступ к буферу (например, см. Мой ответ на этот пост ). Но для Unix это не работает.
  • Я могу увеличить размер буфера для файла, передав bufferего конструктору, но stdoutон уже создан .
  • python -uОчевидно, что отключение буферизации ( ) только ухудшает ситуацию!
  • При использовании временного буфера возникают те же проблемы - stdoutон сбрасывается после того, как каждый 8192-й байт копируется из временного буфера.

Обоснование: цель здесь - уменьшить мерцание консоли. Буферизация всего, согласно этому вопросу, действительно работает, например, когда я пытаюсь использовать C или используя Windows API в Python, но ограничение 8182 в Python, похоже, вызывает проблемы, которые я не могу обойти в Unix.

Ответы

1 blhsing Nov 27 2020 at 05:29

Вы можете обернуть необработанный поток stdout, доступный как sys.stdout.buffer, с большим размером буфера io.BufferedWriter, а затем обернуть полученный буферизованный двоичный поток как буферизованный текстовый поток с помощью io.TextIOWrapper:

import io
import sys

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

Вот демонстрация эффекта увеличения размера буфера stdout до 100000, чтобы он не сбрасывал два вывода печати длиной 10000 символов, пока не будет вызвана ручная очистка:

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

Демо: https://repl.it/@blhsing/UnkemptGullibleDecompiler

1 cz Nov 27 2020 at 16:39

Нашел ответ, на самом деле очень простой:

my_stdout = open( 1, "w", buffering = 100000 )
  • 1это filenoдля stdout.
  • sys.stdout = my_stdoutможно использовать для изменения printцели по умолчанию .
  • Я тестировал это только на Unix.