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/issue28458Também como sugerido neste blog, é possível reabrir
sys.stdout
no modo sem buffer:Cada operação
stdout.write
eprint
será automaticamente liberada depois.fonte
UnsupportedOperation: IOStream has no fileno.
Com o Python 3.x, a
print()
função foi estendida:Então, você pode fazer:
Entrada de documentos do Python
fonte
O uso da
-u
opção de linha de comando funciona, mas é um pouco desajeitado. Isso significaria que o programa potencialmente se comportaria incorretamente se o usuário invocasse o script sem a-u
opção Eu costumo usar um costumestdout
, assim:... Agora todas as suas
print
chamadas (que são usadassys.stdout
implicitamente) serão automaticamenteflush
editadas.fonte
def __getattr__(self,name): return object.__getattribute__(self.f, name)
Por que não tentar usar um arquivo sem buffer?
OU
fonte
A ideia de Dan não funciona muito bem:
O resultado:
Acredito que o problema é que ele herda da classe de arquivo, o que na verdade não é necessário. De acordo com os documentos para sys.stdout:
tão mudando
para
faz funcionar muito bem.
fonte
Aqui está minha versão, que fornece writelines () e fileno () também:
fonte
file
, recebo um erro. Não háfile
aula.No Python 3, você pode sobrescrever a função de impressão com o padrão definido como
flush = True
fonte
Eu fiz assim no Python 3.4:
fonte
Primeiro, lutei para entender como a opção de descarga estava funcionando. Eu queria fazer um 'display de carregamento' e aqui está a solução que encontrei:
A primeira linha limpa a impressão anterior e a segunda linha imprime uma nova mensagem atualizada. Não sei se existe uma sintaxe de uma linha aqui.
fonte