Zwiększ rozmiar bufora standardowego Pythona
Czy istnieje sposób, aby zwiększyć stdout
rozmiar bufora z 8182 w Pythonie lub opóźnić opróżnianie, dopóki nie zadzwonię flush
?
Rzeczy, które wypróbowałem, ale nie działają:
- Mogę obejść ten problem w systemie Windows, ponieważ mam bezpośredni dostęp do bufora (np. Zobacz moją odpowiedź na ten post ). Ale to nie działa dla Uniksa.
- Mogę zwiększyć rozmiar bufora dla pliku, przekazując
buffer
go do konstruktora, jednakstdout
jest on już skonstruowany. - Wyłączenie buforowania (
python -u
) oczywiście pogarsza sytuację! - Korzystanie z bufora tymczasowego napotyka te same problemy -
stdout
jest opróżniane po skopiowaniu każdego 8192 bajtu z bufora tymczasowego.
Uzasadnienie: Celem jest zmniejszenie migotania konsoli. Buforowanie wszystkiego, zgodnie z tym pytaniem, rzeczywiście działa, na przykład gdy próbuję w C lub używając Windows API w Pythonie, ale limit 8182 w Pythonie wydaje się powodować problemy, których nie mogę obejść na Unixie.
Odpowiedzi
Możesz opakować surowy strumień wyjściowy, dostępny jako sys.stdout.buffer
, z większym rozmiarem buforu io.BufferedWriter
, a następnie zawinąć wynikowy buforowany strumień binarny jako buforowany strumień tekstowy io.TextIOWrapper
:
import io
import sys
sys.stdout = io.TextIOWrapper(io.BufferedWriter(sys.stdout.buffer, new_size))
Oto demonstracja efektu zwiększenia rozmiaru bufora wyjścia standardowego do 100000, aby nie opróżniał dwóch wydruków o długości 10000 znaków, dopóki nie zostanie wywołane ręczne opróżnianie:
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()
Próbny: https://repl.it/@blhsing/UnkemptGullibleDecompiler
Znalazłem odpowiedź, właściwie bardzo prostą:
my_stdout = open( 1, "w", buffering = 100000 )
1
jestfileno
dlastdout
.sys.stdout = my_stdout
można użyć do zmiany domyślnegoprint
celu.- Testowałem to tylko na Uniksie.