¿Cómo vaciar la salida de la impresión Python?
Sugiero cinco formas de hacer esto:
- En Python 3, llame
print(..., flush=True)
(el argumento de vaciado no está disponible en la función de impresión de Python 2, y no hay análogo para la declaración de impresión).
- Llame
file.flush()
al archivo de salida (podemos ajustar la función de impresión de python 2 para hacer esto), por ejemplo,sys.stdout
- aplique esto a cada llamada a la función de impresión en el módulo con una función parcial,
print = partial(print, flush=True)
aplicada al módulo global.
- aplicar esto al proceso con una bandera (
-u
) pasada al comando del intérprete
- aplique esto a cada proceso de Python en su entorno con
PYTHONUNBUFFERED=TRUE
(y desarme la variable para deshacer esto).
Python 3.3+
Con Python 3.3 o superior, solo puede proporcionar flush=True
como argumento de palabra clave a la print
función:
print('foo', flush=True)
Python 2 (o <3.3)
No respaldaron el flush
argumento de Python 2.7. Por lo tanto, si está utilizando Python 2 (o menos de 3.3) y desea un código que sea compatible con 2 y 3, ¿puedo sugerir el siguiente código de compatibilidad? (Tenga en cuenta que la __future__
importación debe estar en / muy "cerca de la parte superior de su 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()
El código de compatibilidad anterior cubrirá la mayoría de los usos, pero para un tratamiento mucho más completo, consulte el six
módulo .
Alternativamente, puede llamar file.flush()
después de imprimir, por ejemplo, con la declaración de impresión en Python 2:
import sys
print 'delayed output'
sys.stdout.flush()
Cambiar el valor predeterminado en un módulo a flush=True
Puede cambiar el valor predeterminado para la función de impresión utilizando functools.partial en el alcance global de un módulo:
import functools
print = functools.partial(print, flush=True)
Si observa nuestra nueva función parcial, al menos en Python 3:
>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)
Podemos ver que funciona igual de normal:
>>> print('foo')
foo
Y en realidad podemos anular el nuevo valor predeterminado:
>>> print('foo', flush=False)
foo
Tenga en cuenta nuevamente, esto solo cambia el alcance global actual, porque el nombre de impresión en el alcance global actual eclipsará la print
función incorporada (o desreferenciará la función de compatibilidad, si usa una en Python 2, en ese alcance global actual).
Si desea hacer esto dentro de una función en lugar de en el ámbito global de un módulo, debe darle un nombre diferente, por ejemplo:
def foo():
printf = functools.partial(print, flush=True)
printf('print stuff like this')
Si lo declara global en una función, lo está cambiando en el espacio de nombres global del módulo, por lo que debe colocarlo en el espacio de nombres global, a menos que ese comportamiento específico sea exactamente lo que desea.
Cambiar el valor predeterminado para el proceso
Creo que la mejor opción aquí es usar la -u
bandera para obtener resultados sin búfer.
$ python -u script.py
o
$ python -um package.module
De los documentos :
Obliga a stdin, stdout y stderr a estar totalmente libres de búfer. En los sistemas donde importa, también ponga stdin, stdout y stderr en modo binario.
Tenga en cuenta que existe un almacenamiento intermedio interno en file.readlines () y File Objects (para la línea en sys.stdin) que no está influenciada por esta opción. Para evitar esto, querrá usar file.readline () dentro de un tiempo 1: bucle.
Cambiar el valor predeterminado para el entorno operativo de shell
Puede obtener este comportamiento para todos los procesos de Python en el entorno o entornos que heredan del entorno si establece la variable de entorno en una cadena no vacía:
por ejemplo, en Linux u OSX:
$ export PYTHONUNBUFFERED=TRUE
o Windows:
C:\SET PYTHONUNBUFFERED=TRUE
de los documentos :
PYTHONUNBUFFERED
Si se establece en una cadena no vacía, es equivalente a especificar la opción -u.
Apéndice
Aquí está la ayuda sobre la función de impresión de Python 2.7.12 - tenga en cuenta que no hay 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__
versión no incluyeflush
porque "el argumento de vaciado se agregó en Python 3.3 (después de que print () se exportó a 2.7 a través de una importación futura)" bugs.python.org/issue28458Además, como se sugiere en este blog, se puede volver
sys.stdout
a abrir en modo sin búfer:Cada una
stdout.write
y laprint
operación se enjuagarán automáticamente después.fuente
UnsupportedOperation: IOStream has no fileno.
Con Python 3.x la
print()
función se ha ampliado:Entonces, solo puedes hacer:
Entrada de documentos de Python
fuente
Usar el
-u
interruptor de línea de comandos funciona, pero es un poco torpe. Significaría que el programa podría comportarse incorrectamente si el usuario invocara el script sin la-u
opción. Usualmente uso una costumbrestdout
, como esta:... Ahora todas sus
print
llamadas (que se usansys.stdout
implícitamente) serán editadas automáticamenteflush
.fuente
def __getattr__(self,name): return object.__getattribute__(self.f, name)
¿Por qué no intentar usar un archivo sin búfer?
O
fuente
La idea de Dan no funciona del todo:
El resultado:
Creo que el problema es que hereda de la clase de archivo, lo que en realidad no es necesario. Según los documentos para sys.stdout:
tan cambiante
a
hace que funcione bien.
fuente
Aquí está mi versión, que también proporciona writelines () y fileno ():
fuente
file
, obtengo un error. No hayfile
claseEn Python 3 puede sobrescribir la función de impresión con el valor predeterminado establecido en
flush = True
fuente
Lo hice así en Python 3.4:
fuente
Primero me costó entender cómo funcionaba la opción de descarga. Quería hacer una 'pantalla de carga' y aquí está la solución que encontré:
La primera línea vacía la impresión anterior y la segunda línea imprime un nuevo mensaje actualizado. No sé si existe una sintaxis de una línea aquí.
fuente