J'essaie de sous-classer la classe file
intégrée en Python pour ajouter quelques fonctionnalités supplémentaires à stdin
et stdout
. Voici le code que j'ai jusqu'à présent:Comment sous-classez-vous le type de fichier en Python?
class TeeWithTimestamp(file):
"""
Class used to tee the output of a stream (such as stdout or stderr) into
another stream, and to add a timestamp to each message printed.
"""
def __init__(self, file1, file2):
"""Initializes the TeeWithTimestamp"""
self.file1 = file1
self.file2 = file2
self.at_start_of_line = True
def write(self, text):
"""Writes text to both files, prefixed with a timestamp"""
if len(text):
# Add timestamp if at the start of a line; also add [STDERR]
# for stderr
if self.at_start_of_line:
now = datetime.datetime.now()
prefix = now.strftime('[%H:%M:%S] ')
if self.file1 == sys.__stderr__:
prefix += '[STDERR] '
text = prefix + text
self.file1.write(text)
self.file2.write(text)
self.at_start_of_line = (text[-1] == '\n')
Le but est d'ajouter un horodatage au début de chaque message, et de se connecter à tout un fichier journal. Cependant, le problème que je tombe sur est que si je fais ceci:
# log_file has already been opened
sys.stdout = TeeWithTimestamp(sys.stdout, log_file)
Puis, quand je tente de faire print 'foo'
, je reçois un ValueError: I/O operation on closed file
. Je ne peux pas appeler de façon significative file.__init__()
dans mon __init__()
, puisque je ne veux pas ouvrir un nouveau fichier, et je ne peux pas attribuer self.closed = False
non plus, puisqu'il s'agit d'un attribut en lecture seule.
Comment puis-je modifier ceci afin que je puisse faire print 'foo'
, et qu'il prenne en charge tous les attributs et méthodes standard file
?
Je ne sais pas exactement quelle fonction j'aurai besoin, mais j'aimerais bien que certaines des plus utilisées soient implémentées. Je suppose que je vais juste mordre la balle et mettre en œuvre ceux dont j'ai besoin, et dériver de l'objet au lieu du fichier. –
Quelles sont les méthodes autres que l'écriture sont couramment utilisés sur sys.stdout? Peut-être que les writelines, close, flush - tout est assez facile (et vous devrez les implémenter vous-même de toute façon - comment le type de fichier pourrait-il fermer ou vider vos deux fichiers?) -) –
Ouais, vous avez raison , en regardant par-dessus l'interface de fichier, tout ce dont j'ai vraiment besoin est d'écrire, d'écrire, de fermer, et de faire flush. Tout le reste ne devrait jamais être appelé sur sys.stdout ou sys.stderr. –