Passer des informations à votre script depuis votre terminal, interrompre son exécution ou encore savoir sur quel système d'exploitation il tourne : la bibliothèque standard sys agit comme un pont entre votre code et l'interpréteur Python.
Récupérer les arguments de la ligne de commande avec sys.argv
Sans doute la fonctionnalité la plus connue du module, sys.argv permet de récupérer les arguments passés à votre script lorsque vous l'exécutez depuis le terminal.
C'est simple : sys.argv est une liste Python.
import sys # Vérifions si l'utilisateur a passé un argument if len(sys.argv) > 1: # On récupère le premier argument après le nom du script nom_utilisateur = sys.argv[1] print(f"Bonjour {nom_utilisateur} !") else: print("Bonjour Patrick ! (utilisateur par défaut)")
Si vous lancez ce script dans votre terminal :
-
python
main.pyaffiche"Bonjour Patrick ! (utilisateur par défaut)" -
python bonjour.py Sebastienaffichera"Bonjour Sebastien !"
Attention
sys.argv contient toujours le nom du script que vous exécutez. Les arguments que vous passez commencent à l'index 1, et tous les arguments récupérés sont de type chaîne de caractères.
Contenu de sys.argv
Quitter un script avec sys.exit()
Parfois, votre script rencontre une situation où il ne peut pas continuer : un fichier manquant, une erreur de connexion à une base de données, etc. Plutôt que de générer une erreur pour un utilisateur final, vous pouvez utiliser sys.exit().
import sys import os if not os.path.exists("config.json"): print("Fichier de config introuvable.") sys.exit(1)
import sys def connect_db(): # Fonction fictive raise ConnectionError("hôte introuvable") try: connexion = connect_db() except Exception as e: print(f"Impossible de se connecter : {e}") sys.exit(1)
Pourquoi mettre 1 dans sys.exit(1) ?
Vous avez remarqué que dans les exemples précédents nous avons passé le chiffre 1 à sys.exit(1).
-
sys.exit(0)indique que le script s'est terminé avec succès. D'ailleurs, si votre script se termine normalement, sans erreur, Python renvoie naturellement un code0au système d'exploitation -
sys.exit(1)(ou tout autre entier positif) indique au système d'exploitation qu'une erreur s'est produite. Si le 1 est le standard pour une erreur générale, vous pouvez définir vos propres codes (2, 3, etc.) selon les conventions de votre projet. Cela permet à un autre programme de comprendre la cause de l'échec
sys.exit() ou raise ?
-
Utilisez
raisesi vous créez une fonction destinée à être utilisée par d'autres développeurs -
Utilisez
sys.exit()si vous écrivez un script final destiné à être lancé depuis un terminal. Si Patrick oublie un argument, un fichier de configuration, etc., le script s'arrête proprement après avoir affiché un message clair
Inspecter le cœur des exceptions avec sys.exc_info()
La fonction sys.exc_info() renvoie un tuple contenant trois informations sur la dernière exception levée : le type d'erreur, l'instance de l'exception et le traceback.
import sys import traceback def diviser_par_zero(): return 10 / 0 try: diviser_par_zero() except Exception: type_erreur, valeur_erreur, tb = sys.exc_info() print(f"Type : {type_erreur}") # Type : <class 'ZeroDivisionError'> print(f"Message : {valeur_erreur}") # Message : division by zero print("Traceback complet :") traceback.print_tb(tb) # Le traceback complet de l'erreur
À noter
Dans 99 % des cas, manipuler directement l'objet erreur avec as e est suffisant. En Python 3, vous pouvez même accéder au traceback via e.__traceback__ sans avoir besoin de sys.exc_info().
Cette fonction reste utile dans quelques cas spécifiques :
-
Accès hors du bloc
except:en'existe que dans leexcept, alors quesys.exc_info()peut être appelé depuis une fonction utilitaire qui s'exécute dans ce contexte sans avoir reçueen paramètre -
Intégration avec certaines API : des outils comme le module
loggingont été conçus pour recevoir le triplet(type, valeur, traceback)directement — c'est exactement ce que renvoiesys.exc_info()en une seule ligne -
Code legacy : vous le croiserez dans du code Python 2 ou des librairies anciennes qui n'ont pas migré vers
as e
Gérer les flux standards : sys.stdin, sys.stdout et sys.stderr
Lorsque vous utilisez la fonction native print(), celle-ci écrit dans sys.stdout. Mais il est possible de séparer les messages d'information et les messages d'erreur.
-
sys.stdout: le flux de sortie standard -
sys.stderr: le flux d'erreur standard (les messages d'alerte ou d'erreur) -
sys.stdin: le flux d'entrée standard (ce que l'on tape au clavier par exemple)
import sys # C'est exactement ce que fait print() en arrière-plan sys.stdout.write("Ceci est un message classique.") # Envoyer un message dans le flux d'erreur sys.stderr.write("Alerte rouge : Patrick a encore effacé la base de données !")
De cette manière, vous pourrez rediriger uniquement les erreurs vers un fichier de log tout en laissant les messages standards s'afficher à l'écran.
À noter
Pourquoi s'embêter avec sys.stderr alors qu'il existe le module logging ? Encore une fois, dans la vie de tous les jours, on ne s'en sert quasiment jamais directement. À la limite pour des cas particuliers comme le chaînage de commandes dans un terminal.
Exemple avec grep dans le terminal
Ici, grep "bob" ne trouve aucune correspondance dans stdout ; le message "alice" est filtré et disparaît. En revanche, "Traitement de alice..." s'affiche quand même, car il a été écrit dans stderr, qui court-circuite complètement le pipe.
Manipuler l'environnement d'exécution
Comment Python cherche les modules importables
Lorsque vous faites un import mon_module, Python cherche ce fichier dans une liste précise de répertoires : sys.path.
import sys print("Python cherche les modules dans ces répertoires :") for chemin in sys.path: print(chemin)
sys.path sur ma sandbox
Le premier élément est toujours le répertoire contenant le fichier exécuté, ce qui permet d'importer directement les modules locaux sans configuration particulière.
Cette liste contient toujours les chemins vers la bibliothèque standard, mais aussi, lorsqu'un environnement virtuel est activé, le dossier site-packages propre à ce venv. C'est d'ailleurs ce dernier chemin qui confirme qu'un venv est bien actif : il pointe vers le dossier du projet plutôt que vers le site-packages global de l'installation Python.
À noter
Vous pouvez forcer Python à indexer d'autres sources via sys.path.append("/chemin/vers/le/dossier/secret/de/patrick") pour pouvoir importer les modules contenus dans ce dossier.
Le registre des modules (sys.modules)
Une fois les modules trouvés, pour rester performant, Python utilise sys.modules en les stockant dans un dictionnaire.
Quand vous faites import mon_module, Python lit et exécute tout le code qui s'y trouve. Si vous importiez ce fichier dans plusieurs scripts différents de votre projet, il faudrait réexécuter le code à chaque fois !
En réalité, Python vérifie d'abord si le module est déjà inscrit dans le dictionnaire sys.modules. S'il n'y est pas, Python lit le fichier, l'exécute et place l'information dans le dictionnaire. S'il y est déjà, Python ignore l'exécution et donne accès à l'objet déjà chargé en mémoire.
import sys import math print(sys.modules["math"]) # Affiche le module math, qui est déjà chargé dans sys.modules # Vérifions si le module math est bien enregistré if "math" in sys.modules: print("Le module math est déjà chargé, Python n'aura pas à relire son code !")
Connaître son OS et sa version
Il est possible de connaître le système d'exploitation sur lequel tourne votre programme grâce à sys.
import sys print(sys.platform) # darwin (c'est macOS)
Et on peut même récupérer la version de Python qui est utilisée pour votre programme :
import sys print(sys.version) # 3.14.0 (main, Oct 13 2025, 11:39:28) [Clang 17.0.0 (clang-1700.3.19.1)]
On pourrait même évoquer sys.version_info :
import sys print(sys.version_info) # sys.version_info(major=3, minor=14, micro=0, releaselevel='final', serial=0)
Les petits bonus de la bibliothèque
Inspecter la mémoire avec sys.getsizeof()
C'est vrai que nous ne sommes pas forcément du genre à nous préoccuper de la gestion de la mémoire avec Python (coucou les développeurs C 👋), mais je suis sûr que vous vous êtes déjà demandé combien de RAM occupait une variable.
Pour les curieux, sys.getsizeof() est votre ami :
import sys chaine_courte = "Patrick" chaine_longue = "Patrick aime beaucoup coder en Python avec Sébastien" liste_vide = [] # La taille est renvoyée en octets (bytes) print(f"Taille de la chaîne courte : {sys.getsizeof(chaine_courte)} octets") # Taille de la chaîne courte : 48 octets print(f"Taille de la chaîne longue : {sys.getsizeof(chaine_longue)} octets") # Taille de la chaîne longue : 109 octets print(f"Taille d'une liste vide : {sys.getsizeof(liste_vide)} octets") # Taille d'une liste vide : 56 octets
Repousser les limites de la récursion
Quel beau titre, j'avoue que j'étais inspiré. Si vous avez déjà fait de la récursivité, comme moi, vous avez sûrement eu droit à la RecursionError. J'avais mal géré la condition d'arrêt de ma fonction récursive ; heureusement que, par défaut, Python limite la récursion à 1 000 appels.
Mais si vous savez ce que vous faites, vous pouvez repousser cette limite :
import sys # Connaître la limite actuelle limite = sys.getrecursionlimit() print(f"La limite actuelle est de {limite} appels.") # La limite actuelle est de 1000 appels. # L'augmenter (avec prudence !) sys.setrecursionlimit(2000) print(f"Nouvelle limite : {sys.getrecursionlimit()} appels.") # Nouvelle limite : 2000 appels.
On est d'accord sur le fait que l'on n'utilise pas tous les jours le module sys. Au moment où j'écris ces lignes, je me dis qu'un article sur le module argparse serait parfait pour rester dans le thème.