¿Cómo limpiar la salida de la función de impresión?


¿Cómo fuerzo la función de impresión de Python a la pantalla?

Esto no es un duplicado de Disable output buffering - la pregunta vinculada está intentando una salida sin búfer, mientras que esto es más general. Las respuestas principales en esa pregunta son demasiado poderosas o involucradas para esta (no son buenas respuestas para esta), y esta pregunta puede ser encontrada en Google por un novato relativo.

Author: martineau, 2008-10-23

14 answers

 1083
Author: CesarB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-08 03:38:23

Ejecutando python -h, veo una opción de línea de comandos :

- u: stdout binario sin búfer y stderr; también PYTHONUNBUFFERED = x consulte la página de manual para obtener detalles sobre el almacenamiento interno en búfer relacionado con' - u '

Aquí está el documento pertinente.

 295
Author: gimel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-23 18:06:49

Desde Python 3.3, puede forzar la función normal print() a flush sin la necesidad de usar sys.stdout.flush(); simplemente establezca el argumento de la palabra clave "flush" en true. De la documentación :

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

Imprime objetos en el archivo de flujo, separados por sep y seguidos por end. sep, end y file, si están presentes, deben darse como argumentos de palabras clave.

Todos los argumentos que no son palabras clave se convierten a cadenas como str () does y escritas en la secuencia, separadas por sep y seguidas por end. Tanto sep como end deben ser cadenas; también pueden ser None, lo que significa usar los valores predeterminados. Si no se dan objetos, print () simplemente escribirá end.

El argumento file debe ser un objeto con un método write(string); si no está presente o None, sys.se utilizará stdout. Si la salida se almacena en búfer normalmente se determina por file, pero si el argumento de la palabra clave flush es true, la secuencia es arrojado a la fuerza.

 250
Author: Eugene Sajine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-22 00:32:20

¿Cómo limpiar la salida de Python print?

Sugiero cinco maneras de hacer esto:

  • En Python 3, llame a print(..., flush=True) (el argumento flush no está disponible en la función print de Python 2, y no hay un análogo para la instrucción print).
  • Llama a file.flush() en el archivo de salida (podemos envolver la función print de python 2 para hacer esto), por ejemplo, sys.stdout
  • aplique esto a cada llamada de función de impresión en el módulo con una función parcial,
    print = partial(print, flush=True) aplicada al módulo global.
  • aplique esto al proceso con una bandera (-u) pasada al comando intérprete
  • aplique esto a todos los procesos de python en su entorno con PYTHONUNBUFFERED=TRUE (y desactive la variable para deshacer esto).

Python 3.3 +

Usando Python 3.3 o superior, solo puede proporcionar flush=True como un argumento de palabra clave para la función print:

print('foo', flush=True) 

Python 2 (o

No retroportaron el argumento flush a Python 2.7, por lo que si estás usando Python 2 (o menos que 3.3), y quieres código que sea compatible con 2 y 3, puedo sugerir el siguiente código de compatibilidad. (Tenga en cuenta que la importación __future__ 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 módulo six .

Alternativamente, puede llamar a file.flush() después de imprimir, por ejemplo, con la instrucción print 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 de la función print utilizando functools.parcial sobre el alcance global de un módulo:

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

Si nos fijamos en 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 que lo normal: {[34]]}

>>> print('foo')
foo

Y en realidad podemos anular el nuevo valor predeterminado:

>>> print('foo', flush=False)
foo

Tenga en cuenta de nuevo, esto solo cambia el ámbito global actual, porque el nombre de impresión en el ámbito global actual eclipsará la función builtin print (o desreferenciará la función de compatibilidad, si usa Python 2, en ese ámbito 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 declaras global en una función, lo estás cambiando en el espacio de nombres global del módulo, por lo que solo debes ponerlo en el espacio de nombres global, a menos que ese comportamiento específico es exactamente lo que quieres.

Cambiar el valor predeterminado para el proceso

Creo que la mejor opción aquí es usar la bandera -u para obtener una salida sin búfer.

$ python -u script.py

O

$ python -um package.module

De los documentos :

Forzar que stdin, stdout y stderr estén totalmente sin búfer. En los sistemas donde importa, también ponga stdin, stdout y stderr en modo binario.

Tenga en cuenta que hay almacenamiento en búfer interno en el archivo.readlines () y Objetos File (para línea en sys.stdin) que no está influenciada por esta opción. Para solucionar esto, querrá usar file.readline() dentro de un bucle while 1:.

Cambiando el valor predeterminado para el entorno operativo del 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 o OSX:

$ export PYTHONUNBUFFERED=TRUE

O Windows:

C:\SET PYTHONUNBUFFERED=TRUE

De los documentos :

PYTHONUNBUFFERED

Si esto se establece en una cadena no vacía es equivalente a especificar la opción-u.


Adición

Aquí está la ayuda sobre la función de impresión de Python 2.7.12-tenga en cuenta que hay no 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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-08 00:43:04

También como se sugiere en este blog uno puede reabrir sys.stdout en modo sin búfer:

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

Cada operación stdout.write y print se descargará automáticamente después.

 65
Author: Antony Hatchkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-01 16:25:12

Usando el conmutador de línea de comandos -u funciona, pero es un poco torpe. Esto significaría que el programa podría comportarse incorrectamente si el usuario invoca el script sin la opción -u. Normalmente uso un stdout personalizado, 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)

... Ahora todas tus llamadas print (que usan sys.stdout implícitamente), serán automáticamente flushed.

 31
Author: Dan Lenski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-04 19:51:33

Con Python 3.x extendieron la función print():

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

Entonces, puedes hacer:

print("Visiting toilet", flush=True)

Entrada de documentos de Python

 30
Author: Noah Krasser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-30 11:50:10

¿Por qué no intentar usar un archivo sin búfer?

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

O

sys.stdout = open('out.log', 'a', 0)
 17
Author: Nakilon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-13 07:43:45
import sys
print 'This will be output immediately.'
sys.stdout.flush()
 12
Author: Dynamic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-12 07:51:57

La idea de Dan no funciona del todo:

#!/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"

El resultado:

Traceback (most recent call last):
  File "./passpersist.py", line 12, in <module>
    print "foo"
ValueError: I/O operation on closed file

Creo que el problema es que hereda de la clase file, lo que en realidad no es necesario. Según los documentos de sys.stdout:

Stdout y stderr no necesitan estar integrados objetos de archivo: cualquier objeto es aceptable siempre y cuando tenga un método write() eso requiere un argumento de cadena.

Tan cambiante

class flushfile(file):

A

class flushfile(object):

Hace que funcione bien.

 10
Author: Kamil Kisiel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-13 22:22:20

Aquí está mi versión, que también proporciona writelines() y fileno ():

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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-21 15:36:58

Me encantó la solución de 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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-15 18:19:42

En Python 3 puede sobrescribir la función de impresión con el valor predeterminado 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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-15 19:13:34

Lo hice así en 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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-15 15:22:01