limpiar - python flush file




¿Cómo vaciar la salida de la función de impresión? (10)

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

Esto no es un duplicado de Deshabilitar el almacenamiento en búfer de salida : la pregunta vinculada es intentar 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 esto), y esta pregunta puede ser encontrada en Google por un novato relativo.


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

Sugiero cinco formas de hacer esto:

  • En Python 3, call print(..., flush=True) (el argumento flush no está disponible en la función de impresión de Python 2, y no hay un análogo para la declaración de impresión).
  • Llame a file.flush() en el archivo de salida (podemos envolver la función de impresión 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) 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 elimine la variable para deshacer esto).

Python 3.3+

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

print('foo', flush=True) 

Python 2 (o <3.3)

No respaldaron el argumento de flush a Python 2.7 Por lo tanto, si está usando 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 de __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 declaración de impresión en Python 2:

import sys
print 'delayed output'
sys.stdout.flush()

Cambiar el valor predeterminado en un módulo para 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 podemos anular el nuevo valor predeterminado:

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

Tenga en cuenta de nuevo que esto solo cambia el alcance global actual, porque el nombre de impresión en el alcance global actual eclipsará la función de print integrada (o elimina la función de compatibilidad, si 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 solo debe ponerlo en el espacio de nombres global, a menos que ese comportamiento específico sea exactamente lo que desea.

Cambiando el valor predeterminado para el proceso.

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

$ python -u script.py

o

$ python -um package.module

De la docs :

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

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

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 o OSX:

$ export PYTHONUNBUFFERED=TRUE

o Windows:

C:\SET PYTHONUNBUFFERED=TRUE

de los docs :

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 un argumento de vaciado:

>>> 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.

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

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

O

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

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

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

Entonces, solo puedes hacer:

print("Visiting toilet", flush=True)

Entrada de documentos de Python


Desde Python 3.3, puede forzar la función normal de print() para que se sys.stdout.flush() sin necesidad de usar sys.stdout.flush() ; simplemente configura el argumento de la palabra clave "flush" como verdadero. De la documentación :

imprimir (* objetos, sep = '', final = '\ n', archivo = sys.stdout, flush = Falso)

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

Todos los argumentos que no son de palabras clave se convierten en cadenas como hace str () y se escriben en la secuencia, separados por sep y seguidos por el final. Tanto el sep como el final deben ser cuerdas; también pueden ser Ninguno, lo que significa usar los valores predeterminados. Si no se dan objetos, print () solo escribirá el final.

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


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

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

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, que en realidad no es necesario. Según los documentos para sys.stdout:

stdout y stderr no necesitan ser objetos de archivo integrados: cualquier objeto es aceptable siempre que tenga un método write () que tome un argumento de cadena.

tan cambiante

class flushfile(file):

a

class flushfile(object):

hace que funcione bien.


Me encantó la solución de Dan! Para python3 hacer:

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)

También, como se sugiere en este blog, se puede volver a abrir sys.stdout en modo sin búfer:

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

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


import sys
print 'This will be output immediately.'
sys.stdout.flush()







flush