Comment vider la sortie de l'impression 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 (nous pouvons envelopper la fonction d'impression de python 2 pour ce faire), par exemple,sys.stdout
- appliquer cela à chaque appel de fonction d'impression dans le module avec une fonction partielle,
print = partial(print, flush=True)
appliquée au module global.
- appliquer cela au processus avec un flag (
-u
) passé à la commande interprète
- appliquez ceci à chaque processus python de votre environnement avec
PYTHONUNBUFFERED=TRUE
(et désactivez la variable pour l'annuler).
Python 3.3+
En utilisant Python 3.3 ou supérieur, vous pouvez simplement fournir flush=True
comme argument de mot clé à la print
fonction:
print('foo', flush=True)
Python 2 (ou <3.3)
Ils n'ont pas rétroporté l' flush
argument vers Python 2.7 Donc, si vous utilisez Python 2 (ou moins de 3,3), et que vous voulez du code compatible avec 2 et 3, puis-je suggérer le code de compatibilité suivant. (Notez que l' __future__
importation doit être à / très "près du 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 couvrira la plupart des utilisations, mais pour un traitement beaucoup plus approfondi, consultez le six
module .
Alternativement, vous pouvez simplement appeler file.flush()
après l'impression, par exemple, avec l'instruction print en Python 2:
import sys
print 'delayed output'
sys.stdout.flush()
Changer la valeur par défaut d'un module en flush=True
Vous pouvez modifier la valeur par défaut de la fonction d'impression en utilisant 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, au 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 fait remplacer la nouvelle valeur par défaut:
>>> print('foo', flush=False)
foo
Notez à nouveau que cela ne modifie que la portée globale actuelle, car le nom d'impression sur la portée globale actuelle éclipsera la print
fonction intégrée (ou annulera la référence de la fonction de compatibilité, si vous en utilisez une en Python 2, dans cette portée globale actuelle).
Si vous souhaitez le faire à l'intérieur d'une fonction plutôt que sur la portée globale d'un module, vous devez lui donner 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 changez dans l'espace de noms global du module, vous devez donc simplement le mettre dans l'espace de noms global, à moins que ce comportement spécifique ne soit exactement ce que vous voulez.
Modification de la valeur par défaut du processus
Je pense que la meilleure option ici est d'utiliser le -u
drapeau pour obtenir une sortie sans tampon.
$ python -u script.py
ou
$ python -um package.module
De la documentation :
Force stdin, stdout et stderr à être totalement sans tampon. Sur les systèmes où cela est important, mettez également stdin, stdout et stderr en mode binaire.
Notez qu'il existe un tampon interne dans file.readlines () et File Objects (pour la ligne dans sys.stdin) qui n'est pas influencé 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 qui héritent 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
à partir des documents :
PYTHONUNBUFFERED
Si ce paramètre est défini sur une chaîne non vide, cela équivaut à spécifier l'option -u.
Addenda
Voici l'aide sur la fonction d'impression de Python 2.7.12 - notez qu'il n'y a pas d' flush
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.
__future__
version ne comprend pasflush
car "l'argument flush a été ajouté dans Python 3.3 (après que print () a été rétroporté vers 2.7 via une future importation)" bugs.python.org/issue28458Aussi, comme suggéré dans ce blog, on peut rouvrir
sys.stdout
en mode sans tampon:Chaque opération
stdout.write
etprint
sera automatiquement rincée par la suite.la source
UnsupportedOperation: IOStream has no fileno.
Avec Python 3.x, la
print()
fonction a été étendue:Donc, vous pouvez simplement faire:
Entrée Python Docs
la source
L'utilisation du
-u
commutateur de ligne de commande fonctionne, mais c'est un peu maladroit. Cela signifierait que le programme se comporterait potentiellement de manière incorrecte si l'utilisateur invoquait le script sans l'-u
option. J'utilise habituellement une coutumestdout
, comme ceci:... Maintenant, tous vos
print
appels (qui utilisentsys.stdout
implicitement), seront automatiquementflush
édités.la source
def __getattr__(self,name): return object.__getattribute__(self.f, name)
Pourquoi ne pas essayer d'utiliser un fichier sans tampon?
OU
la source
L'idée de Dan ne fonctionne pas tout à fait:
Le résultat:
Je crois que le problème est qu'il hérite de la classe de fichiers, ce qui n'est pas vraiment nécessaire. Selon les documents pour sys.stdout:
si changeant
à
le fait fonctionner très bien.
la source
Voici ma version, qui fournit également writelines () et fileno ():
la source
file
, j'obtiens une erreur. Il n'y a pas defile
cours.Dans Python 3, vous pouvez remplacer la fonction d'impression avec la valeur par défaut définie sur
flush = True
la source
Je l'ai fait comme ça en Python 3.4:
la source
J'ai d'abord eu du mal à comprendre comment fonctionnait l'option de vidage. Je voulais faire un 'affichage de chargement' et voici la solution que j'ai trouvée:
La première ligne efface l'impression précédente et la deuxième ligne imprime un nouveau message mis à jour. Je ne sais pas si une syntaxe sur une ligne existe ici.
la source