J'utilise une bibliothèque Python qui fait quelque chose sur un objet
do_something(my_object)
et le change. Ce faisant, il imprime des statistiques sur stdout, et j'aimerais avoir une idée de ces informations. La bonne solution serait de changer do_something()
pour renvoyer les informations pertinentes,
out = do_something(my_object)
mais il faudra un certain temps avant que les développeurs do_something()
se penchent sur ce problème. Pour contourner le problème, j'ai pensé à analyser tout ce qui do_something()
écrit sur stdout.
Comment puis-je capturer la sortie stdout entre deux points dans le code, par exemple,
start_capturing()
do_something(my_object)
out = end_capturing()
?
Réponses:
Essayez ce gestionnaire de contexte:
Usage:
output
est maintenant une liste contenant les lignes imprimées par l'appel de fonction.Utilisation avancée:
Ce qui n'est peut-être pas évident, c'est que cela peut être fait plus d'une fois et les résultats concaténés:
Production:
Mise à jour : ils ont été ajoutés
redirect_stdout()
àcontextlib
Python 3.4 (avecredirect_stderr()
). Vous pouvez donc l'utiliserio.StringIO
pour obtenir un résultat similaire (bienCapturing
qu'être une liste et un gestionnaire de contexte soit sans doute plus pratique).la source
.extend()
place afin qu'il puisse être utilisé de manière concaténante, comme vous l'avez remarqué. :-)self._stringio.truncate(0)
après l'self.extend()
appel dans la__exit__()
méthode pour libérer une partie de la mémoire détenue par le_stringio
membre.from io import StringIO
place de la première ligne dans le gestionnaire de contexte.En python> = 3.4, contextlib contient un
redirect_stdout
décorateur. Il peut être utilisé pour répondre à votre question comme ceci:À partir de la documentation :
la source
f = io.StringIO() with redirect_stdout(f): logger = getLogger('test_logger') logger.debug('Test debug message') out = f.getvalue() self.assertEqual(out, 'DEBUG:test_logger:Test debug message')
. Cela me donne une erreur:AssertionError: '' != 'Test debug message'
logger.debug
n'écrit pas dans stdout par défaut. Si vous remplacez votre appel de journal par,print()
vous devriez voir le message.stream_handler = logging.StreamHandler(sys.stdout)
. Et ajoutez ce gestionnaire à mon enregistreur. il devrait donc écrire sur stdout et l'redirect_stdout
attraper, non?Voici une solution asynchrone utilisant des canaux de fichiers.
Exemple d'utilisation:
la source