J'utilise python ftplib
pour écrire un petit client FTP, mais certaines des fonctions du package ne retournent pas de sortie de chaîne, mais impriment sur stdout
. Je veux rediriger stdout
vers un objet dont je pourrai lire la sortie.
Je sais que je stdout
peux être redirigé vers n'importe quel fichier régulier avec:
stdout = open("file", "a")
Mais je préfère une méthode qui n'utilise pas le lecteur local.
Je recherche quelque chose comme le BufferedReader
en Java qui peut être utilisé pour envelopper un tampon dans un flux.
stdout = open("file", "a")
lui seul redirigera quoi que ce soit.Réponses:
la source
stdout
objet d' origine , car il est toujours disponible sursys.__stdout__
. Voir docs.python.org/library/sys.html#sys.__stdout__ .finally:
bloc, il est donc également réaffecté si une exception est levée entre les deux.try: bkp = sys.stdout ... ... finally: sys.stdout = bkp
Il existe une fonction contextlib.redirect_stdout () dans Python 3.4:
Voici un exemple de code qui montre comment l'implémenter sur les anciennes versions de Python .
la source
redirect_stderr
le dernier Python!Juste pour ajouter à la réponse de Ned ci-dessus: vous pouvez l'utiliser pour rediriger la sortie vers n'importe quel objet qui implémente une méthode write (str) .
Cela peut être utilisé à bon escient pour "capturer" la sortie stdout dans une application GUI.
Voici un exemple idiot dans PyQt:
la source
À partir de Python 2.6, vous pouvez utiliser tout ce qui implémente l'
TextIOBase
API du module io en remplacement. Cette solution vous permet également d'utilisersys.stdout.buffer.write()
en Python 3 pour écrire des chaînes d'octets (déjà) encodées dans stdout (voir stdout dans Python 3 ). UtiliserStringIO
ne fonctionnerait pas alors, car nisys.stdout.encoding
nisys.stdout.buffer
ne seraient disponibles.Une solution utilisant TextIOWrapper:
Cette solution fonctionne pour Python 2> = 2.6 et Python 3.
Veuillez noter que notre nouveau
sys.stdout.write()
n'accepte que les chaînes Unicode etsys.stdout.buffer.write()
n'accepte que les chaînes d'octets. Ce n'est peut-être pas le cas pour l'ancien code, mais c'est souvent le cas pour le code qui est construit pour s'exécuter sur Python 2 et 3 sans modifications, qui à nouveau utilise souventsys.stdout.buffer
.Vous pouvez créer une légère variante qui accepte les chaînes unicode et d'octets pour
write()
:Vous n'êtes pas obligé de définir l'encodage du tampon sys.stdout.encoding, mais cela aide lorsque vous utilisez cette méthode pour tester / comparer la sortie de script.
la source
Cette méthode restaure sys.stdout même s'il y a une exception. Il obtient également n'importe quelle sortie avant l'exception.
Testé en Python 2.7.10 avec
io.BytesIO()
Testé en Python 3.6.4 avec
io.StringIO()
Bob, ajouté pour un cas si vous pensez que quelque chose de l'expérimentation de code modifié / étendu pourrait devenir intéressant dans n'importe quel sens, sinon n'hésitez pas à le supprimer
la source
Un gestionnaire de contexte pour python3:
utiliser comme ceci:
la source
Dans Python3.6, les modules
StringIO
etcStringIO
ont disparu, vous devriez les utiliser à laio.StringIO
place, vous devriez donc faire ceci comme la première réponse:la source
Utilisez
pipe()
et écrivez dans le descripteur de fichier approprié.https://docs.python.org/library/os.html#file-descriptor-operations
la source
Voici une autre prise à ce sujet.
contextlib.redirect_stdout
avecio.StringIO()
comme documenté c'est super, mais c'est quand même un peu bavard pour une utilisation quotidienne. Voici comment en faire un one-liner en sous-classantcontextlib.redirect_stdout
:Puisque __enter__ retourne self, vous avez l'objet de gestionnaire de contexte disponible après la sortie du bloc with. De plus, grâce à la méthode __repr__, la représentation sous forme de chaîne de l'objet gestionnaire de contexte est en fait stdout. Alors maintenant tu as,
la source