Uso do método sys.stdout.flush ()

Respostas:

173

A saída padrão do Python é armazenada em buffer (o que significa que ele coleta alguns dados "gravados" na saída padrão antes de gravá-los no terminal). A chamada sys.stdout.flush()obriga a "liberar" o buffer, o que significa que ele gravará tudo no buffer no terminal, mesmo que normalmente esperasse antes de fazê-lo.

Aqui estão algumas boas informações sobre E / S (des) armazenadas em buffer e por que são úteis:
http://en.wikipedia.org/wiki/Data_buffer IO armazenado em buffer ou não armazenado em
buffer

Castanho Haldean
fonte
@Ciastopiekarz O que podemos fazer para que o buffer seja liberado no Windows?
helplessKirk
@Ciastopiekarz Como você figura? Se eu pegar o script Python de Andrew Clark e substituir a linha de impressão sys.stdout.write("%d" % i), preciso descomentar a chamada para sys.stdout.flush()que o buffer seja exibido enquanto o script está em execução.
Bacon Bits
119

Considere o seguinte script Python simples:

import time
import sys

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

Isso foi projetado para imprimir um número a cada segundo por cinco segundos, mas se você o executar como está agora (dependendo do buffer padrão do sistema), poderá não ver nenhuma saída até que o script seja concluído e, de repente, você verá 0 1 2 3 4impresso para a tela.

Isso ocorre porque a saída está sendo armazenada em buffer e, a menos que você libere sys.stdoutum após printo outro, não verá a saída imediatamente. Remova o comentário da sys.stdout.flush()linha para ver a diferença.

Andrew Clark
fonte
48
No Python 3.x, 'print i' deve ser substituído por print (i, end = '') porque print () no Python 3 possui um prefixo padrão end = '\ n' que solicita que o console seja liberado.
ofer.sheffer
5
Estou apenas confuso, quando removo a vírgula, ela está funcionando bem como esperado. Existe alguma lógica de buffer para novas linhas?
Sunil Lulla
7

De acordo com meu entendimento, sempre que executarmos instruções de impressão, a saída será gravada no buffer. E veremos a saída na tela quando o buffer for liberado (limpo). Por padrão, o buffer será liberado quando o programa sair. MAS TAMBÉM PODEMOS LIMPAR O BUFFER MANUALMENTE usando a instrução "sys.stdout.flush ()" no programa. No código abaixo, o buffer será liberado quando o valor de i atingir 5.

Você pode entender executando o código abaixo.

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
fonte
Falta uma vírgula após o print ide obter a sua saída
SwimBikeRun
1
import sys
for x in range(10000):
    print "HAPPY >> %s <<\r" % str(x),
    sys.stdout.flush()
JieJ
fonte
1

De acordo com meu entendimento, sys.stdout.flush () envia todos os dados que foram armazenados em buffer nesse ponto para um objeto de arquivo. Enquanto estiver usando stdout, os dados são armazenados na memória buffer (por algum tempo ou até a memória ficar cheia) antes de serem gravados no terminal. O uso de flush () força para esvaziar o buffer e gravar no terminal mesmo antes que o buffer tenha espaço vazio.

Sagar Dhungel
fonte