Question

Comment forcer la fonction d'impression de Python à s'afficher à l'écran?

Ceci n'est pas une copie de Désactiver la mise en mémoire tampon de sortie - la question liée tente de ne pas être mise en mémoire tampon sortie, alors que cela est plus général. Les réponses principales dans cette question sont trop puissantes ou impliquées pour celle-ci (ce ne sont pas de bonnes réponses pour cela), et cette question peut être trouvée sur Google par un nouveau débutant.

Était-ce utile?

La solution

import sys
sys.stdout.flush()

print imprime par défaut sur sys.stdout.

Références

Python 2

Python 3

Autres conseils

En cours d'exécution python -h, je vois une option de ligne de commande :

  

-u: stdout et stderr binaires sans mémoire tampon; aussi PYTHONUNBUFFERED = x            voir la page de manuel pour plus de détails sur la mise en mémoire tampon interne relative à '-u'

Voici le le document pertinent .

Depuis Python 3.3, vous pouvez forcer le vidage de la fonction normale print() sans qu'il soit nécessaire d'utiliser sys.stdout.flush(); il suffit de définir le & "; flush &"; argument de mot clé à true. De la documentation :

  

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

     

Imprimez les objets dans le fichier de flux, séparés par sep et suivis par fin. sep, end et file, le cas échéant, doivent être spécifiés en tant qu'arguments de mots clés.

     

Tous les arguments non-mot-clé sont convertis en chaînes comme le fait str () et écrits dans le flux, séparés par sep et suivis par fin. Les deux sep et end doivent être des chaînes; ils peuvent également être Aucun, ce qui signifie utiliser les valeurs par défaut. Si aucun objet n'est donné, print () écrira simplement end.

     

L'argument du fichier doit être un objet avec une méthode write (string); S'il n'est pas présent ou None, sys.stdout sera utilisé. Le type de sortie en mémoire tampon est généralement déterminé par fichier. Toutefois, si le mot clé flush est défini sur true, le flux est vidé de force.

  

Comment vider la sortie des impressions Python?

Je suggère cinq façons de procéder:

  • Dans Python 3, appelez print(..., flush=True) (l'argument flush n'est pas disponible dans la fonction d'impression de Python 2 et il n'y a pas d'analogue pour l'instruction print).
  • Appelez file.flush() le fichier de sortie (pour cela, vous pouvez encapsuler la fonction d'impression de python 2), par exemple, sys.stdout
  • l'appliquer à chaque appel de fonction d'impression dans le module avec une fonction partielle,
    print = partial(print, flush=True) appliqué au module global.
  • applique cela au processus avec un indicateur (-u) transmis à la commande d'interpréteur
  • appliquez-le à tous les processus python de votre environnement avec PYTHONUNBUFFERED=TRUE (et désélectionnez la variable pour annuler cela).

Python 3.3 +

Avec Python version 3.3 ou ultérieure, vous pouvez simplement fournir flush=True en tant qu'argument de mot clé à la print fonction:

print('foo', flush=True) 

Python 2 (ou < 3.3)

Ils n'ont pas rétroporté l'argument flush dans Python 2.7. Par conséquent, si vous utilisez Python 2 (ou une version inférieure à 3.3) et souhaitez un code compatible à la fois avec 2 et 3, puis-je vous suggérer le code de compatibilité suivant. (Notez que l’importation __future__ doit être à / very & Quot; près des haut de votre module "):

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

Le code de compatibilité ci-dessus couvre la plupart des utilisations, mais pour un traitement beaucoup plus approfondi, voir le six module .

Vous pouvez également appeler <=> après l'impression, par exemple, avec l'instruction print en Python 2:

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

Modification de la valeur par défaut dans un module en <=>

Vous pouvez modifier la valeur par défaut de la fonction d'impression à l'aide de functools.partial sur la portée globale d'un module:

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

si vous regardez notre nouvelle fonction partielle, du moins en Python 3:

>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)

Nous pouvons voir que cela fonctionne comme d'habitude:

>>> print('foo')
foo

Et nous pouvons en réalité remplacer le nouveau paramètre par défaut:

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

Notez à nouveau que cela modifie uniquement la portée globale actuelle, car le nom d’impression de la portée globale actuelle occultera la fonction <=> intégrée (ou déréférencera la fonction de compatibilité, si vous utilisez Python 2, dans cette portée globale actuelle).

Si vous souhaitez effectuer cette opération dans une fonction plutôt que dans la portée globale d'un module, vous devez lui attribuer un nom différent, par exemple:

.
def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')

Si vous le déclarez global dans une fonction, vous le modifiez dans l'espace de noms global du module. Vous devez donc simplement le placer dans l'espace de noms global, à moins que ce comportement ne corresponde exactement à vos souhaits.

Modification de la valeur par défaut du processus

Je pense que la meilleure option ici est d'utiliser l'indicateur <=> pour obtenir une sortie non tamponnée.

$ python -u script.py

ou

$ python -um package.module

Dans les docs :

  

Forcez stdin, stdout et stderr à ne pas bouger. Sur les systèmes où cela compte, mettez également stdin, stdout et stderr en mode binaire.

     

Notez que la mise en mémoire tampon interne dans file.readlines () et les objets de fichier (pour la ligne dans sys.stdin) ne sont pas influencés par cette option. Pour contourner ce problème, vous souhaiterez utiliser file.readline () dans une boucle while: 1.

Modification de la valeur par défaut pour l'environnement d'exploitation du shell

Vous pouvez obtenir ce comportement pour tous les processus python de l'environnement ou des environnements hérités de l'environnement si vous définissez la variable d'environnement sur une chaîne non vide:

Par exemple, sous Linux ou OSX:

$ export PYTHONUNBUFFERED=TRUE

ou Windows:

C:\SET PYTHONUNBUFFERED=TRUE

depuis le docs :

  

PYTHONUNBUFFERED

     

Si ceci est défini sur une chaîne non vide, cela équivaut à spécifier l'option -u.

Annoncedendum

Voici l'aide sur la fonction d'impression de Python 2.7.12 - notez qu'il y a non <=> argument:

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

Aussi, comme suggéré dans ce blog , vous pouvez le rouvrir. sys.stdout en mode sans tampon:

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

Chaque stdout.write et print opération sera automatiquement vidée par la suite.

Avec Python 3.x, la fonction print() a été étendue:

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

Donc, vous pouvez simplement faire:

print("Visiting toilet", flush=True)

Entrée de documents Python

L’utilisation du commutateur de ligne de commande -u fonctionne, mais elle est un peu maladroite. Cela signifierait que le programme pourrait se comporter de manière incorrecte si l'utilisateur invoquait le script sans l'option stdout. J'utilise habituellement une coutume print, comme ceci:

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)

... Maintenant, tous vos sys.stdout appels (qui utilisent flush implicitement) seront automatiquement édités <=>.

Pourquoi ne pas utiliser un fichier sans tampon?

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

OU

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

L'idée de Dan ne fonctionne pas très bien:

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

Le résultat:

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

Je pense que le problème est qu’il hérite de la classe de fichiers, ce qui n’est en fait pas nécessaire. Selon la documentation de sys.stdout:

  

stdout et stderr ne doivent pas & # 8217; ne pas être intégrés   objets de fichier: tout objet est acceptable   tant qu'il a une méthode write ()   qui prend un argument de chaîne.

donc changeant

class flushfile(file):

à

class flushfile(object):

ça marche très bien.

Voici ma version, qui fournit également writeelines () et 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, vous pouvez écraser la fonction d'impression avec la valeur par défaut flush = True

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

Je l'ai fait comme ça 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...')
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top