Wykorzystanie metody sys.stdout.flush ()

Odpowiedzi:

173

Standardowe wyjście Pythona jest buforowane (co oznacza, że ​​zbiera on część danych „zapisywanych” na standardowe wyjście, zanim zapisze je na terminalu). Powołaniesys.stdout.flush() zmusza go do "opróżnienia" bufora, co oznacza, że ​​zapisze wszystko w buforze na terminalu, nawet jeśli normalnie zaczeka przed zrobieniem tego.

Oto kilka dobrych informacji na temat (nie) buforowanych operacji we / wy i dlaczego jest to przydatne:
http://en.wikipedia.org/wiki/Data_buffer
Buffered vs niebuforowany IO

Haldean Brown
źródło
@Ciastopiekarz Co możemy zrobić, aby opróżnić bufor w systemie Windows?
bezradny
@Ciastopiekarz Jak oceniasz? Jeśli wezmę skrypt w języku Python Andrew Clarka i zamienię linię drukowania na sys.stdout.write("%d" % i), muszę odkomentować wywołanie, aby sys.stdout.flush()bufor był wyświetlany podczas wykonywania skryptu.
Bacon Bits
119

Rozważmy następujący prosty skrypt w Pythonie:

import time
import sys

for i in range(5):
    print(i),
    #sys.stdout.flush()
    time.sleep(1)

Ma to na celu wypisywanie jednej liczby co sekundę przez pięć sekund, ale jeśli uruchomisz go tak, jak jest teraz (w zależności od domyślnego buforowania systemu), możesz nie zobaczyć żadnych danych wyjściowych do zakończenia działania skryptu, a następnie zobaczysz wszystko naraz 0 1 2 3 4 wydrukowane do ekranu.

Dzieje się tak, ponieważ dane wyjściowe są buforowane i jeśli nie opróżnisz ich sys.stdoutpo każdym print, nie zobaczysz ich natychmiast. Usuń komentarz z sys.stdout.flush()linii, aby zobaczyć różnicę.

Andrew Clark
źródło
48
W Pythonie 3.x, 'print i' należy zastąpić print (i, end = ''), ponieważ print () w Pythonie 3 ma domyślny prefiks end = '\ n', który zachęca konsolę do opróżnienia.
ofer.sheffer
5
Jestem po prostu zdezorientowany, kiedy usuwam przecinek, działa dobrze zgodnie z oczekiwaniami. Czy istnieje logika bufora dla nowych linii?
Sunil Lulla
7

Zgodnie z moim rozumieniem, kiedy kiedykolwiek wykonamy instrukcje print, dane wyjściowe zostaną zapisane w buforze. I zobaczymy dane wyjściowe na ekranie, gdy bufor zostanie opróżniony (wyczyszczony). Domyślnie bufor zostanie opróżniony po zakończeniu programu. ALE MOŻEMY RÓWNIEŻ RĘCZNIE PRZEPŁUKAĆ BUFOR, używając w programie instrukcji "sys.stdout.flush ()". W poniższym kodzie bufor zostanie opróżniony, gdy wartość i osiągnie 5.

Możesz to zrozumieć, wykonując poniższy kod.

chiru@online:~$ cat flush.py
import time
import sys

for i in range(10):
    print i
    if i == 5:
        print "Flushing buffer"
        sys.stdout.flush()
    time.sleep(1)

for i in range(10):
    print i,
    if i == 5:
        print "Flushing buffer"
        sys.stdout.flush()
chiru@online:~$ python flush.py 
0 1 2 3 4 5 Flushing buffer
6 7 8 9 0 1 2 3 4 5 Flushing buffer
6 7 8 9
chiru
źródło
Brak przecinka po przecinku, print iaby uzyskać dane wyjściowe
SwimBikeRun
1
import sys
for x in range(10000):
    print "HAPPY >> %s <<\r" % str(x),
    sys.stdout.flush()
JieJ
źródło
1

Jak rozumiem, sys.stdout.flush () wypycha wszystkie zbuforowane dane do tego punktu do obiektu pliku. Podczas korzystania ze standardowego wyjścia dane są przechowywane w pamięci buforowej (przez pewien czas lub do zapełnienia pamięci), zanim zostaną zapisane na terminalu. Użycie flush () wymusza opróżnienie bufora i zapis do terminala, nawet zanim bufor będzie miał puste miejsce.

Sagar Dhungel
źródło