Suis-je capable de surcharger la fonction print
et d'appeler la fonction normale de l'intérieur? Ce que je veux faire, c'est après une ligne spécifique, je veux que print
appelle mon print
qui appellera la normale print
et écrit une copie dans un fichier.
Je ne sais pas non plus comment surcharger print
. Je ne sais pas comment faire des arguments de longueur variable. Je vais le chercher bientôt mais surcharge python d'impression vient de me dire que je ne peux pas surcharger print
dans 2.x qui est ce que j'utilise.
Pour ceux qui examinent les réponses précédemment datées, à partir de la version "Python 2.6", il y a une nouvelle réponse à la question de l'affiche originale.
Dans Python 2.6 et plus, vous pouvez désactiver l'instruction print en faveur de la fonction print, puis remplacer la fonction print par votre propre fonction print:
from __future__ import print_function
# This must be the first statement before other statements.
# You may only put a quoted or triple quoted string,
# Python comments, other future statements, or blank lines before the __future__ line.
try:
import __builtin__
except ImportError:
# Python 3
import builtins as __builtin__
def print(*args, **kwargs):
"""My custom print() function."""
# Adding new arguments to the print function signature
# is probably a bad idea.
# Instead consider testing if custom argument keywords
# are present in kwargs
__builtin__.print('My overridden print() function!')
return __builtin__.print(*args, **kwargs)
Bien sûr, vous devez tenir compte du fait que cette fonction d'impression ne concerne que le module à ce stade. Vous pouvez choisir de remplacer __builtin__.print
, mais vous devrez enregistrer l'original __builtin__.print
; probablement déblayage avec le __builtin__
espace de noms.
La surcharge print
est une fonctionnalité de conception de python 3.0 pour remédier à votre manque de capacité à le faire dans python 2.x.
Cependant, vous pouvez remplacer sys.stdout. ( exemple .) Affectez-le simplement à un autre objet de type fichier qui fait ce que vous voulez.
Alternativement, vous pouvez simplement diriger votre script via la commande unix tee
. python yourscript.py | tee output.txt
sera imprimé à la fois sur stdout et sur output.txt, mais cela capturera toutes les sorties.
J'ai rencontré le même problème.
Que dis-tu de ça:
class writer :
def __init__(self, *writers) :
self.writers = writers
def write(self, text) :
for w in self.writers :
w.write(text)
import sys
saved = sys.stdout
fout = file('out.log', 'w')
sys.stdout = writer(sys.stdout, fout)
print "There you go."
sys.stdout = saved
fout.close()
Cela a fonctionné comme un charme pour moi. Il a été tiré de http://mail.python.org/pipermail/python-list/2003-F February/188788.html
class MovieDesc:
name = "Name"
genders = "Genders"
country = "Country"
def __str__(self):
#Do whatever you want here
return "Name: {0}\tGenders: {1} Country: {2} ".format(self.name,self.genders,self.country)
)
Bien que vous ne puissiez pas remplacer le mot clé print
(dans Python 2.x print
est un mot clé), il est courant de remplacer sys.stdout
pour faire quelque chose de similaire à print
surcharger; par exemple, avec une instance de StringIO.StringIO
. Cela capturera toutes les données imprimées dans l'instance StringIO
, après quoi vous pourrez les manipuler.
En Python 2.x vous ne pouvez pas, car print n'est pas une fonction, c'est une déclaration. En Python 3 print est une fonction, donc je supposons qu'il puisse être outrepassé (je ne l'ai pas essayé, cependant).
Pour un exemple très simple, à partir de Python3.4 (non testé avec des versions plus anciennes) cela fonctionne bien pour moi (placé en haut du module):
import time
def dprint(string):
__builtins__.print("%f -- %s" % (time.time(), string))
print = dprint
Remarque, cela ne fonctionne que si le paramètre de chaîne est une chaîne ... YMMV
pensais juste que j'ajouterais mon idée ... convenait à mes objectifs de pouvoir exécuter sthg dans Eclipse, puis exécuter à partir de l'interface de ligne de commande (Windows) sans obtenir d'exceptions d'encodage avec chaque instruction d'impression. Quoi que vous fassiez, ne faites pas d'EncodingStdout une sous-classe du fichier de classe: la ligne "self.encoding = encoding" entraînerait alors l'attribut d'encodage étant None!
NB une chose que j'ai découverte au cours d'une journée aux prises avec ce genre de choses est que l'exception d'encodage est levée AVANT d'arriver à "imprimer" ou "écrire": c'est lorsque la chaîne paramétrée (c'est-à-dire "mondodod% s blah blah% s"% ( "blip", "blap")) est construit par ... quoi ??? le "cadre"?
class EncodingStdout( object ):
def __init__( self, encoding='utf-8' ):
self.encoding = encoding
def write_ln( self, *args ):
if len( args ) < 2:
sys.__stdout__.write( args[ 0 ] + '\n' )
else:
if not isinstance( args[ 0 ], basestring ):
raise Exception( "first arg was %s, type %s" % ( args[ 0 ], type( args[ 0 ]) ))
# if the default encoding is UTF-8 don't bother with encoding
if sys.getdefaultencoding() != 'utf-8':
encoded_args = [ args[ 0 ] ]
for i in range( 1, len( args )):
# numbers (for example) do not have an attribute "encode"
if hasattr( args[ i ], 'encode' ):
encoded_args.append( args[ i ].encode( self.encoding, 'replace' ) )
else:
encoded_args.append( args[ i ])
args = encoded_args
sys.__stdout__.write( args[ 0 ] % Tuple( args[ 1 : ] ) + '\n' )
# write seems to need a flush
sys.__stdout__.flush()
def __getattr__( self, name ):
return sys.__stdout__.__getattribute__( name )
print "=== A mondodod %s %s" % ( "été", "pluviôse, irritée contre la ville entière" )
sys.stdout = EncodingStdout()
sys.stdout.write_ln( "=== B mondodod %s %s", "été", "pluviôse, irritée contre la ville entière" )
# convenience method
def pr( *args ):
sys.stdout.write_ln( *args )
pr( "=== C mondodod %s %s", "été", "pluviôse, irritée contre la ville entière" )
J'ai répondu à la même question sur une autre SO question
Essentiellement, la solution la plus simple consiste à simplement rediriger la sortie vers stderr comme suit, dans le fichier de configuration wsgi.
sys.stdout = sys.stderr