Como liberar a saída da impressão Python?
Sugiro cinco maneiras de fazer isso:
- No Python 3, chame
print(..., flush=True)
(o argumento flush não está disponível na função de impressão do Python 2 e não há analógico para a instrução print).
- Chame
file.flush()
o arquivo de saída (podemos envolver a função de impressão do python 2 para fazer isso), por exemplo,sys.stdout
- aplique isso a todas as chamadas de função de impressão no módulo com uma função parcial,
print = partial(print, flush=True)
aplicada ao módulo global.
- aplique isso ao processo com uma flag (
-u
) passada para o comando intérprete
- aplique isso a todos os processos python em seu ambiente com
PYTHONUNBUFFERED=TRUE
(e desative a variável para desfazer isso).
Python 3.3 ou superior
Usando o Python 3.3 ou superior, você pode apenas fornecer flush=True
como argumento de palavra-chave a print
função:
print('foo', flush=True)
Python 2 (ou <3.3)
Eles não suportaram o flush
argumento no Python 2.7. Portanto, se você estiver usando o Python 2 (ou menos do que 3.3) e quiser um código compatível com o 2 e o 3, sugiro o seguinte código de compatibilidade. (Observe que a __future__
importação deve estar / muito "perto da parte superior 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 cobrirá a maioria dos usos, mas para um tratamento muito mais completo, consulte o six
módulo .
Como alternativa, você pode simplesmente ligar file.flush()
após a impressão, por exemplo, com a instrução print no Python 2:
import sys
print 'delayed output'
sys.stdout.flush()
Alterando o padrão em um módulo para flush=True
Você pode alterar o padrão da função de impressão usando functools.partial no escopo 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 no Python 3:
>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)
Podemos ver que funciona como normal:
>>> print('foo')
foo
E podemos substituir o novo padrão:
>>> print('foo', flush=False)
foo
Observe novamente que isso altera apenas o escopo global atual, porque o nome de impressão no escopo global atual ofuscará a print
função interna (ou não fará referência à função de compatibilidade, se estiver usando uma no Python 2, nesse escopo global atual).
Se você deseja fazer isso dentro de uma função, em vez de no escopo global de um módulo, deve atribuir um nome diferente, por exemplo:
def foo():
printf = functools.partial(print, flush=True)
printf('print stuff like this')
Se você o declarar global em uma função, você o está alterando no espaço para nome global do módulo, portanto, você deve colocá-lo no espaço para nome global, a menos que esse comportamento específico seja exatamente o que você deseja.
Alterando o padrão para o processo
Eu acho que a melhor opção aqui é usar a -u
flag para obter uma saída sem buffer.
$ python -u script.py
ou
$ python -um package.module
Dos documentos :
Força stdin, stdout e stderr a serem totalmente inalterados. Nos sistemas onde importa, coloque também stdin, stdout e stderr no modo binário.
Observe que há buffer interno em file.readlines () e objetos de arquivo (para linha em sys.stdin) que não é influenciado por esta opção. Para contornar isso, convém usar file.readline () dentro de um tempo 1: loop.
Alterando o Padrão para o Ambiente Operacional Shell
Você pode obter esse comportamento para todos os processos python no ambiente ou ambientes herdados do ambiente, se você definir a variável de ambiente como uma sequência não vazia:
por exemplo, no Linux ou OSX:
$ export PYTHONUNBUFFERED=TRUE
ou Windows:
C:\SET PYTHONUNBUFFERED=TRUE
dos documentos :
PYTHONUNBUFFERED
Se isso estiver definido como uma sequência não vazia, será equivalente a especificar a opção -u.
Termo aditivo
Aqui está a ajuda na função de impressão do Python 2.7.12 - observe que não há 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.
__future__
versão não incluiflush
porque "o argumento de flush foi adicionado no Python 3.3 (após a impressão () ter sido suportada para 2.7 através de uma importação futura)" bugs.python.org/issue28458