Contactez-nous

Redirection des entrées/sorties

Découvrez comment rediriger les entrées et sorties standard (stdin, stdout, stderr) de vos programmes Python. Lisez des données depuis un fichier au lieu du clavier, écrivez la sortie dans un fichier au lieu de la console, et gérez les erreurs séparément.

Entrées/sorties standard : stdin, stdout, stderr

La plupart des programmes en ligne de commande (y compris les scripts Python) utilisent trois flux de données standard :

  • stdin (standard input) : Le flux d'entrée standard. Par défaut, il est connecté au clavier. C'est de là que proviennent les données lues par la fonction `input()`.
  • stdout (standard output) : Le flux de sortie standard. Par défaut, il est connecté à la console (le terminal). C'est là que `print()` affiche les données.
  • stderr (standard error) : Le flux de sortie d'erreur standard. Par défaut, il est également connecté à la console. Il est utilisé pour afficher les messages d'erreur.

Ces flux sont des *objets fichiers* (ou des objets qui se comportent comme des fichiers) en Python. Vous pouvez y accéder via le module `sys` :

  • `sys.stdin`
  • `sys.stdout`
  • `sys.stderr`

L'intérêt de ces flux standard est qu'ils peuvent être *redirigés*.

Redirection au niveau du système d'exploitation (ligne de commande)

La redirection la plus courante se fait au niveau du système d'exploitation, en utilisant les opérateurs de redirection de la ligne de commande (shell) :

  • `>` : Redirige la sortie standard (stdout) vers un fichier. Ecrase le contenu du fichier s'il existe déjà.
  • `>>` : Redirige la sortie standard (stdout) vers un fichier, en ajoutant les données à la fin du fichier.
  • `<` : Redirige l'entrée standard (stdin) depuis un fichier.
  • `2>` : Redirige la sortie d'erreur standard (stderr) vers un fichier.
  • `2>&1` : Redirige stderr vers le même endroit que stdout.
  • `|` (pipe) : Connecte la sortie standard d'une commande à l'entrée standard d'une autre commande.

Exemples (ligne de commande, pas du code Python) :

# Exécuter mon_script.py et écrire la sortie dans sortie.txt (écrase le fichier)
python mon_script.py > sortie.txt

# Exécuter mon_script.py et ajouter la sortie à la fin de sortie.txt
python mon_script.py >> sortie.txt

# Exécuter mon_script.py en utilisant entree.txt comme entrée standard
python mon_script.py < entree.txt

# Exécuter mon_script.py et rediriger les erreurs vers erreurs.txt
python mon_script.py 2> erreurs.txt

# Exécuter mon_script.py, rediriger la sortie vers sortie.txt et les erreurs vers erreurs.txt
python mon_script.py > sortie.txt 2> erreurs.txt

# Exécuter mon_script.py et rediriger stdout et stderr vers le même fichier
python mon_script.py > sortie.txt 2>&1

# Exécuter commande1, et utiliser sa sortie comme entrée pour commande2 (pipe)
commande1 | commande2

Ces redirections sont gérées par le *shell* (l'interpréteur de commandes), pas par Python lui-même. Elles sont très utiles pour chaîner des commandes, traiter des fichiers, et automatiser des tâches.

Redirection à l'intérieur d'un script Python

Il est également possible de rediriger les entrées/sorties standard *à l'intérieur* d'un script Python, en modifiant les objets `sys.stdin`, `sys.stdout`, et `sys.stderr`.

Cependant, cette pratique est généralement *déconseillée* pour les scripts simples, car elle rend le code moins flexible et moins testable. Il est souvent préférable de laisser la redirection au niveau du système d'exploitation.

Si vous devez vraiment le faire, voici comment procéder :

import sys

# Rediriger stdout vers un fichier
with open("sortie.txt", "w") as f:
    original_stdout = sys.stdout  # Sauvegarder le stdout original
    sys.stdout = f              # Rediriger stdout vers le fichier
    print("Ceci sera écrit dans sortie.txt")
    # ... (tout ce qui est affiché avec print() ira dans sortie.txt) ...

sys.stdout = original_stdout  # Restaurer le stdout original

print("Ceci sera affiché à la console")

Dans cet exemple :

  1. On ouvre un fichier en écriture (`sortie.txt`).
  2. On sauvegarde la valeur originale de `sys.stdout` (la console) dans une variable.
  3. On affecte l'objet fichier à `sys.stdout`. A partir de ce moment, tous les appels à `print()` écriront dans le fichier, et non plus à la console.
  4. On effectue les opérations qui doivent écrire dans le fichier.
  5. On restaure la valeur originale de `sys.stdout` (la console).

Il est *crucial* de restaurer la valeur originale de `sys.stdout` après avoir terminé, sinon votre programme ne pourra plus afficher de texte à la console.

Vous pouvez faire de même pour `sys.stdin` (pour lire depuis un fichier au lieu du clavier) et `sys.stderr` (pour rediriger les erreurs).

Notez que la redirection à l'intérieur du script affecte *toutes* les opérations d'entrée/sortie, y compris celles des modules importés. Cela peut avoir des conséquences inattendues.

Une approche plus propre pour rediriger la sortie d'une fonction spécifique est d'utiliser le décorateur `contextlib.redirect_stdout` (voir le module `contextlib`).

Bonnes pratiques et alternatives

Voici quelques bonnes pratiques et alternatives pour la redirection des entrées/sorties :

  • Privilégiez la redirection au niveau du système d'exploitation : C'est généralement la méthode la plus simple, la plus flexible, et la plus portable.
  • Utilisez des arguments de ligne de commande pour spécifier les fichiers d'entrée/sortie : Au lieu de rediriger `stdin` et `stdout`, votre script peut prendre des noms de fichiers en argument et les ouvrir explicitement. Cela rend le code plus clair et plus facile à tester. Vous pouvez utiliser le module `argparse` pour gérer les arguments de ligne de commande.
  • Utilisez des fonctions et des paramètres : Si vous avez besoin de lire des données depuis différentes sources, ou d'écrire des données vers différentes destinations, passez les objets fichiers (ou des objets similaires) en argument à vos fonctions.
  • N'utilisez la redirection interne (`sys.stdin`, `sys.stdout`, `sys.stderr`) qu'en dernier recours : Si vous devez vraiment le faire, soyez très prudent et assurez-vous de restaurer les valeurs originales.
  • Documentez clairement : Si votre script s'attend à ce que les entrées/sorties soient redirigées, documentez-le clairement.