Como descarregar a saída da função de impressão?

como é que obrigo a função de impressão do Python a sair para o ecrã?

Isto não é um duplicado de desactivar o 'buffer' de saída - a questão ligada está a tentar um resultado não-barrado, enquanto isto é mais geral. As respostas de topo nessa pergunta são muito poderosas ou envolvidas para este (eles não são boas respostas para isso), e esta pergunta pode ser encontrada no Google por um novato relativo.

Author: martineau, 2008-10-23

14 answers

 1083
Author: CesarB, 2016-01-08 03:38:23

Em execução python -h, vejo uma opção da linha de comandos :

- u: stdout binário não-sufferido e stderr; também PYTHONUNBUFFERED = x veja a página do homem para mais detalhes sobre o '- u '

Aqui está o relevante doc .

 295
Author: gimel, 2008-10-23 18:06:49

Desde o Python 3. 3, você pode forçar a função normal print() a puxar o autoclismo sem a necessidade de usar sys.stdout.flush(); Basta definir o argumento da palavra-chave "flush" como verdadeiro. Da documentação:

Print (*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

Imprimir os objectos no ficheiro stream, separados por sep e seguidos pelo fim. sep, end e file, se estiverem presentes, devem ser indicados como argumentos de palavra-chave.

Todos os argumentos sem palavras-chave são convertidos para strings como str () faz e escreve para o fluxo, separado por sep e seguido por fim. Tanto sep quanto end devem ser strings; eles também podem ser nenhum, o que significa usar os valores padrão. Se não forem indicados objectos, print () irá apenas escrever o fim.

O argumento do ficheiro deve ser um objecto com um método de escrita( string); se não estiver presente ou nenhum, sys.stdout será usado. Se o resultado é buffer é normalmente determinado por ficheiro, mas se o argumento da palavra-chave flush for verdadeiro, o fluxo é corado à força.

 250
Author: Eugene Sajine, 2014-10-22 00:32:20

Como descarregar o resultado da impressão em Python?

Sugiro cinco maneiras de fazer isto:
  • em Python 3, call print(..., flush=True) (o argumento flush não está disponível na função de impressão do Python 2, e não existe nenhum análogo para a declaração de impressão).
  • chamada file.flush() no ficheiro de saída( podemos embrulhar a função de impressão do python 2 para fazer isto), por exemplo, sys.stdout
  • aplica isto a cada chamada de função de impressão no módulo com uma função parcial,
    print = partial(print, flush=True) aplicado ao módulo global.
  • aplica isto ao processo com uma bandeira (-u) passada ao comando interpretador
  • aplique isto em todos os processos python do seu ambiente com PYTHONUNBUFFERED=TRUE (e desligue a variável para desfazer isto).

Python 3. 3+

Usando o Python 3. 3 ou superior, poderá apenas fornecer flush=True como argumento de palavra-chave para a função print:

print('foo', flush=True) 

Python 2 (ou

Eles não alteraram o argumento flush para o Python 2.7 Então, se você está usando Python 2 (ou menos de 3.3), e quer um código compatível com 2 e 3, posso sugerir o seguinte código de compatibilidade. (Note que __future__ a importação deve ser em / muito "perto do topo do seu módulo"):

from __future__ import print_function
import sys

if sys.version_info[:2] < (3, 3):
    old_print = print
    def print(*args, **kwargs):
        flush = kwargs.pop('flush', False)
        old_print(*args, **kwargs)
        if flush:
            file = kwargs.get('file', sys.stdout)
            # Why might file=None? IDK, but it works for print(i, file=None)
            file.flush() if file is not None else sys.stdout.flush()

O código de compatibilidade acima referido abrangerá a maioria das utilizações, mas para um tratamento muito mais completo, ver o módulo six .

Em alternativa, pode simplesmente ligar para file.flush() depois de imprimir, por exemplo, com a declaração de impressão em Python 2:

import sys
print 'delayed output'
sys.stdout.flush()

Mudar o valor por omissão num módulo para flush=True

Pode alterar o valor por omissão para a função de impressão usando o functools.parcial no âmbito global de um módulo:

import functools
print = functools.partial(print, flush=True)

Se você olhar para a nossa nova função parcial, pelo menos em Python 3:

>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)
Podemos ver que funciona como o normal.
>>> print('foo')
foo
E podemos anular o novo padrão.
>>> print('foo', flush=False)
foo

Note novamente, isto só altera o âmbito global actual, porque o nome da impressão no escopo global atual irá ofuscar a função builtin print (ou dereference a função de compatibilidade, se usando Python 2, nesse escopo global atual).

Se quiser fazer isto dentro de uma função em vez de no âmbito global de um módulo, deve dar-lhe um nome diferente, por exemplo:

def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')

Se o declarar global numa função, está a alterá-lo no espaço de nomes global do módulo, por isso deve colocá-lo no espaço de nomes global, a menos que esse comportamento específico é exactamente o que queres.

Alterar o valor por omissão para o processo

Acho que a melhor opção é usar a bandeira para obter uma saída livre.
$ python -u script.py

Ou

$ python -um package.module

Dos documentos :

Forçar o stdin, o stdout e o stderr a não serem baralhados. Em sistemas onde isso importa, também coloque stdin, stdout e stderr em modo binário.

Note que há 'buffering' interno no ficheiro.objectos de leitura() e ficheiros (para linha em sys.stdin) que não é influenciado por esta opção. Para trabalhar em torno disso, você vai querer usar arquivo.readline () inside a while 1: loop.

Alterar o valor por omissão para o ambiente operacional da shell

Poderá obter este comportamento para todos os processos python no ambiente ou ambientes que herdam do ambiente se definir a variável de ambiente como uma cadeia de caracteres não vazia:

Por exemplo, em Linux ou OSX:

$ export PYTHONUNBUFFERED=TRUE

Ou Windows:

C:\SET PYTHONUNBUFFERED=TRUE

Dos documentos :

PYTHONUNBUFFERED

Se este for definido como um texto não-vazio, é equivalente a indicar a opção-U.


Adenda

Aqui está a ajuda na função de impressão do Python 2.7.12-note que existe Não flush argumento:

>>> from __future__ import print_function
>>> help(print)
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout)

    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file: a file-like object (stream); defaults to the current sys.stdout.
    sep:  string inserted between values, default a space.
    end:  string appended after the last value, default a newline.
 112
Author: Aaron Hall, 2018-06-08 00:43:04

Também como sugerido em Este blog pode-se reabrir sys.stdout em modo livre:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

Cada operação stdout.write e print será automaticamente descarregada depois.

 65
Author: Antony Hatchkins, 2012-04-01 16:25:12

Usar o interruptor da linha de comandos -u funciona, mas é um pouco desajeitado. Isso significaria que o programa poderia comportar-se incorretamente se o usuário invocasse o script sem a opção -u. Eu normalmente uso um costume stdout, como este:

class flushfile(object):
  def __init__(self, f):
    self.f = f

  def write(self, x):
    self.f.write(x)
    self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

... Agora todas as suas chamadas print (que usam sys.stdout implicitamente), serão automaticamente flush ed.

 31
Author: Dan Lenski, 2016-11-04 19:51:33

Com Python 3.x eles estenderam a função print():

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
Então, podes fazer:
print("Visiting toilet", flush=True)

Item De Docs Python

 30
Author: Noah Krasser, 2018-06-30 11:50:10

Porque não tentar usar um ficheiro livre?

f = open('xyz.log', 'a', 0)

Ou

sys.stdout = open('out.log', 'a', 0)
 17
Author: Nakilon, 2012-06-13 07:43:45
import sys
print 'This will be output immediately.'
sys.stdout.flush()
 12
Author: Dynamic, 2011-12-12 07:51:57
A ideia do Dan não funciona.
#!/usr/bin/env python
class flushfile(file):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

print "foo"

O resultado:

Traceback (most recent call last):
  File "./passpersist.py", line 12, in <module>
    print "foo"
ValueError: I/O operation on closed file
Eu acredito que o problema é que ele herda da classe de arquivos, o que na verdade não é necessário. De acordo com os documentos da sys.stdout:
O Stdout e o stderr não precisam de ser incorporados. objectos do ficheiro: qualquer objecto é aceitável desde que tenha um método de escrita() é preciso um argumento.

Tão variável

class flushfile(file):

A

class flushfile(object):
Faz com que funcione bem.
 10
Author: Kamil Kisiel, 2008-11-13 22:22:20

Aqui está a minha versão, que fornece writelines () e fileno(), também:

class FlushFile(object):
    def __init__(self, fd):
        self.fd = fd

    def write(self, x):
        ret = self.fd.write(x)
        self.fd.flush()
        return ret

    def writelines(self, lines):
        ret = self.writelines(lines)
        self.fd.flush()
        return ret

    def flush(self):
        return self.fd.flush

    def close(self):
        return self.fd.close()

    def fileno(self):
        return self.fd.fileno()
 6
Author: guettli, 2015-03-21 15:36:58
Adorei a solução do Dan! Para python3 do:
import io,sys
class flushfile:
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()
sys.stdout = flushfile(sys.stdout)
 5
Author: Jonas Byström, 2013-01-15 18:19:42

No Python 3, poderá sobrepor a função de impressão com o conjunto predefinido para flush = True

def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
    __builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)
 2
Author: user263387, 2016-05-15 19:13:34
Fiz isto assim em Python 3.4:
'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')
 2
Author: kmario23, 2016-08-15 15:22:01