Pregunta

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

Esto no es un duplicado de Deshabilitar el almacenamiento en búfer de salida - la pregunta vinculada intenta generar una salida sin búfer, aunque esto es más general.Las respuestas principales a esa pregunta son demasiado poderosas o complicadas para esta (no son buenas respuestas para esto), y un novato relativamente puede encontrar esta pregunta en Google.

¿Fue útil?

Solución

import sys
sys.stdout.flush()

print por defecto imprime en sys.stdout.

Referencias

Python 2

Python 3

Otros consejos

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

  

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

Aquí está el documento relevante .

Desde Python 3.3, puede forzar que la función print() normal se vacíe sin la necesidad de usar sys.stdout.flush(); solo configure " flush " argumento de palabra clave a verdadero. De la documentación :

  

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

     

Imprime objetos en el archivo continuo, 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 en cadenas como str () y se escriben en la secuencia, separados por sep y seguidos por end. Tanto sep como end deben ser cadenas; También pueden ser Ninguno, lo que significa utilizar los valores predeterminados. Si no se proporcionan objetos, print () simplemente escribirá end.

     

El argumento del archivo debe ser un objeto con un método de escritura (cadena); si no está presente o Ninguno, se usará sys.stdout. Si el resultado se almacena en búfer generalmente se determina por archivo, pero si el argumento de la palabra clave flush es verdadero, el flujo se vacía a la fuerza.

  

¿Cómo vaciar la salida de la impresión Python?

Sugiero cinco formas de hacer esto:

  • En Python 3, llame a 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() en el archivo de salida (podemos ajustar la función de impresión de python 2 para hacer esto), por ejemplo, sys.stdout
  • aplica 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) aplicado al módulo global.
  • aplique 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 desactive la variable para deshacer esto).

Python 3.3+

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

print('foo', flush=True) 

Python 2 (o < 3.3)

No respaldaron el argumento flush a Python 2.7 Entonces, 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 importación __future__ debe estar en / very & Quot; cerca de 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, vea el six módulo .

Alternativamente, puede llamar a <=> 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 <=>

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 que lo normal:

>>> print('foo')
foo

Y en realidad podemos anular el nuevo valor predeterminado:

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

Observe nuevamente, esto solo cambia el alcance global actual, porque el nombre de impresión en el alcance global actual eclipsará la función integrada <=> (o desreferenciará la función de compatibilidad, si se usa Python 2, en ese alcance global actual).

Si desea hacer esto dentro de una función en lugar de en el alcance 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 el indicador <=> para obtener resultados sin búfer.

$ python -u script.py

o

$ python -um package.module

Del documentos :

  

Obliga a stdin, stdout y stderr a estar totalmente libres de búfer. En sistemas donde importa, también ponga stdin, stdout y stderr en modo binario.

     

Tenga en cuenta que hay almacenamiento intermedio interno en file.readlines () y File Objects (para la línea en sys.stdin) que no está influenciado 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.


Anunciodendum

Aquí está la ayuda sobre la función de impresión de Python 2.7.12 - tenga en cuenta que hay no <=> 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.

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 stdout.write y print La operación se lavará automáticamente después.

Con Python 3.x la función print() se ha ampliado:

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

Entonces, puedes hacer:

print("Visiting toilet", flush=True)

Python Docs Entry

El uso del interruptor de línea de comandos -u funciona, pero es un poco torpe. Significaría que el programa podría comportarse incorrectamente si el usuario invocara el script sin la opción stdout. Usualmente uso un print personalizado, como este:

class flushfile:
  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 sus sys.stdout llamadas (que usan flush implícitamente), serán automáticamente <=> ed.

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

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

O

sys.stdout = open('out.log', 'a', 0)

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 de archivo, lo que en realidad no es necesario. De acuerdo con los documentos para sys.stdout:

  

stdout y stderr no necesitan & # 8217; t estar incorporado   objetos de archivo: cualquier objeto es aceptable   siempre que tenga un método write ()   que toma un argumento de cadena.

tan cambiante

class flushfile(file):

a

class flushfile(object):

hace que funcione bien.

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()

En Python 3 puede sobrescribir la función de impresión con el ajuste predeterminado en flush = True

def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
    __builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)

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...')
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top