W3docs

Les modules os et sys de Python

Maîtrisez les modules os et sys de Python : naviguez dans le système de fichiers, gérez les variables d'environnement et les arguments de ligne de commande.

Les modules os et sys font partie des outils de bibliothèque standard les plus essentiels de Python. os fait le lien entre Python et le système d'exploitation sous-jacent — il vous permet de naviguer dans les répertoires, d'inspecter et de définir des variables d'environnement, et de manipuler des fichiers et des chemins. sys fait le lien entre Python et l'interpréteur lui-même — il expose la liste d'arguments, le chemin de recherche des modules et des points d'ancrage pour contrôler la sortie de l'interpréteur. Ensemble, ils couvrent presque tout ce dont un script a besoin pour interagir avec l'environnement dans lequel il s'exécute.

Le module os

Importez os en haut de votre script :

import os

Aucune installation n'est nécessaire ; il est livré avec chaque distribution Python.

Travailler avec les répertoires

Obtenir et modifier le répertoire de travail courant

os.getcwd() retourne le chemin absolu du répertoire dans lequel votre script s'exécute. os.chdir() le modifie.

import os

# Print the current directory
print(os.getcwd())
# Example output: /Users/alice/projects

# Change to a different directory
os.chdir("/tmp")
print(os.getcwd())
# Output: /tmp

Lister le contenu d'un répertoire

os.listdir(path) retourne une liste de toutes les entrées (fichiers et sous-répertoires) dans path. Il ne descend pas récursivement dans les sous-répertoires.

import os

entries = os.listdir(".")   # "." means current directory
for entry in sorted(entries):
    print(entry)

Pour distinguer les fichiers des répertoires, utilisez os.path.isfile() et os.path.isdir() :

import os

for entry in os.listdir("."):
    if os.path.isdir(entry):
        print(f"[DIR]  {entry}")
    else:
        print(f"[FILE] {entry}")

Créer et supprimer des répertoires

import os

# Create a single directory
os.mkdir("reports")

# Create nested directories in one call
os.makedirs("data/2024/january", exist_ok=True)
# exist_ok=True prevents an error if the directory already exists

# Remove an empty directory
os.rmdir("reports")

# Remove a full directory tree
import shutil
shutil.rmtree("data")

Le paramètre exist_ok=True dans os.makedirs() est très utile dans les scripts susceptibles de s'exécuter plusieurs fois — sans lui, une deuxième exécution lève FileExistsError.

Parcourir une arborescence de répertoires

os.walk(top) génère un triplet (dirpath, dirnames, filenames) pour chaque répertoire de l'arborescence enracinée à top. C'est la méthode standard pour parcourir récursivement une structure de dossiers.

import os

for dirpath, dirnames, filenames in os.walk("project"):
    level = dirpath.count(os.sep)
    indent = "  " * level
    print(f"{indent}{os.path.basename(dirpath)}/")
    for filename in filenames:
        print(f"{indent}  {filename}")

Travailler avec les chemins de fichiers

Le sous-module os.path de Python contient des utilitaires portables de manipulation de chemins qui fonctionnent correctement sous Windows, macOS et Linux.

Assembler des composants de chemin

os.path.join() combine des parties d'un chemin en utilisant le séparateur correct pour le système d'exploitation courant.

import os

base = "/home/alice"
project = "myapp"
filename = "config.json"

full_path = os.path.join(base, project, filename)
print(full_path)
# Output: /home/alice/myapp/config.json

Ne construisez jamais des chemins par concaténation de chaînes comme base + "/" + filename — cela ne fonctionne pas sous Windows. Utilisez toujours os.path.join().

Décomposer un chemin

import os

path = "/home/alice/myapp/config.json"

print(os.path.dirname(path))   # /home/alice/myapp
print(os.path.basename(path))  # config.json
print(os.path.split(path))     # ('/home/alice/myapp', 'config.json')
print(os.path.splitext(path))  # ('/home/alice/myapp/config', '.json')

os.path.splitext() est pratique lorsque vous devez retirer ou modifier une extension de fichier.

Vérifier si un chemin existe

import os

print(os.path.exists("/tmp"))      # True (usually)
print(os.path.isfile("/tmp"))      # False — it is a directory
print(os.path.isdir("/tmp"))       # True
print(os.path.isabs("/tmp"))       # True — it is an absolute path

Obtenir le chemin absolu

os.path.abspath() résout les chemins relatifs par rapport au répertoire de travail courant :

import os

print(os.path.abspath("config.json"))
# Example output: /home/alice/myapp/config.json

C'est utile lorsque vous devez stocker ou journaliser un chemin qui doit rester valide même si le répertoire de travail change ultérieurement.

La variable __file__ et les chemins relatifs au script

Un piège classique : un script qui ouvre "data.csv" fonctionne lorsqu'on l'exécute depuis son propre répertoire, mais échoue depuis un autre répertoire. La solution consiste à construire le chemin relatif au fichier script lui-même :

import os

# Directory that contains *this* script
HERE = os.path.dirname(os.path.abspath(__file__))

data_file = os.path.join(HERE, "data.csv")
with open(data_file, encoding="utf-8") as f:
    content = f.read()

Cette technique rend les scripts portables quel que soit le répertoire depuis lequel vous les lancez.

Variables d'environnement

Les variables d'environnement stockent des configurations qui vivent en dehors du code source — URL de bases de données, clés API, indicateurs de fonctionnalités, etc. Le mapping os.environ vous donne un accès en lecture et en écriture à l'environnement du processus courant.

Lire une variable d'environnement

import os

# Returns the value or None if not set
home = os.environ.get("HOME")
print(home)
# Example output: /home/alice

# Raise KeyError if not set (useful to fail fast on missing config)
path = os.environ["PATH"]

Préférez os.environ.get(key) à os.environ[key] sauf si la variable est strictement requise et que le programme doit planter sans elle.

Lire avec une valeur par défaut

import os

debug = os.environ.get("DEBUG", "false")
port = int(os.environ.get("PORT", "8080"))

print(f"debug={debug}, port={port}")
# Output: debug=false, port=8080

Définir et supprimer des variables d'environnement

import os

# Set a variable — affects only the current process and its children
os.environ["MY_APP_ENV"] = "production"

# Remove a variable
os.environ.pop("MY_APP_ENV", None)   # None prevents KeyError if not present

La définition de valeurs dans os.environ ne persiste pas après la fin du processus. Pour définir des variables d'environnement permanentes, modifiez votre profil shell (~/.bashrc, ~/.zshrc) ou utilisez un fichier .env chargé par une bibliothèque telle que python-dotenv.

Lister toutes les variables d'environnement

import os

for key, value in sorted(os.environ.items()):
    print(f"{key}={value}")

Exécuter des commandes shell avec os.system() et subprocess

os.system(command) exécute une commande shell et retourne son code de sortie, mais ne vous permet pas de capturer sa sortie. Pour tout ce qui dépasse un simple appel « lancer et oublier », utilisez plutôt le module subprocess.

import os
import subprocess

# Quick way — exit code only
exit_code = os.system("echo hello")
print("exit code:", exit_code)   # 0 means success

# Better way — capture output
result = subprocess.run(
    ["echo", "hello"],
    capture_output=True,
    text=True,
)
print(result.stdout.strip())   # hello

subprocess.run() est plus puissant et plus sûr que os.system() car il évite l'interpréteur shell et vous permet de capturer stdout, stderr et le code de retour en tant qu'objets Python.

Utilitaires os pratiques

FonctionCe qu'elle fait
os.getcwd()Répertoire de travail courant
os.chdir(path)Changer de répertoire de travail
os.listdir(path)Lister les entrées d'un répertoire
os.mkdir(path)Créer un répertoire
os.makedirs(path, exist_ok=True)Créer des répertoires imbriqués
os.rmdir(path)Supprimer un répertoire vide
os.remove(path)Supprimer un fichier
os.rename(src, dst)Renommer / déplacer un fichier
os.walk(top)Parcourir récursivement une arborescence
os.environMapping des variables d'environnement
os.getpid()ID du processus courant
os.cpu_count()Nombre de cœurs CPU logiques

Le module sys

sys expose des informations sur l'interpréteur Python et vous donne des points d'ancrage pour contrôler son comportement.

import sys

Arguments de ligne de commande avec sys.argv

sys.argv est une liste de chaînes. sys.argv[0] est le nom du script ; les éléments suivants sont les arguments passés en ligne de commande.

Supposons que vous enregistriez ceci sous le nom greet.py et que vous exécutiez python greet.py Alice 42 :

import sys

script_name = sys.argv[0]   # 'greet.py'
name = sys.argv[1]          # 'Alice'
age = sys.argv[2]           # '42' — always a string

print(f"Hello, {name}! You are {age} years old.")
# Output: Hello, Alice! You are 42 years old.

Validez toujours sys.argv avant d'accéder aux indices — une IndexError fera planter le script si l'utilisateur oublie un argument :

import sys

if len(sys.argv) != 3:
    print(f"Usage: python {sys.argv[0]} <name> <age>")
    sys.exit(1)

name = sys.argv[1]
age = sys.argv[2]
print(f"Hello, {name}! You are {age} years old.")

Pour l'analyse d'arguments complexes, préférez le module argparse de la bibliothèque standard — il génère automatiquement une sortie --help.

Quitter l'interpréteur avec sys.exit()

sys.exit(code) lève SystemExit et termine l'interpréteur. Par convention, le code de sortie 0 signifie le succès ; toute valeur non nulle signale une erreur.

import sys

answer = input("Continue? (y/n): ")
if answer.lower() != "y":
    print("Goodbye!")
    sys.exit(0)

print("Continuing...")

Vous pouvez intercepter SystemExit dans un bloc try/except si vous avez besoin d'exécuter un nettoyage avant la fin du programme, mais en général l'instruction with (pour les descripteurs de fichiers, les connexions réseau, etc.) gère automatiquement le nettoyage.

Informations sur la version de Python

import sys

print(sys.version)
# Example: 3.10.15 (main, ...) [GCC 11.4.0]

print(sys.version_info)
# sys.version_info(major=3, minor=10, micro=15, ...)

# Guard against running on an unsupported Python version
if sys.version_info < (3, 8):
    sys.exit("This script requires Python 3.8 or later.")

sys.version_info est un n-uplet nommé, vous pouvez donc le comparer directement à un n-uplet d'entiers.

Le chemin de recherche des modules (sys.path)

Lorsque vous écrivez import mymodule, Python parcourt chaque répertoire de sys.path dans l'ordre jusqu'à trouver un fichier correspondant. La liste commence par le répertoire du script (ou une chaîne vide pour les sessions interactives), suivi des entrées PYTHONPATH, puis de la bibliothèque standard et des site-packages.

import sys

for p in sys.path:
    print(p)

Vous pouvez ajouter des éléments à sys.path à l'exécution pour importer des modules depuis des emplacements non standard :

import sys
import os

# Add a sibling directory to the search path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "libs"))

import mymodule   # now found in ./libs/mymodule.py

Modifier sys.path est une solution rapide pour le développement local, mais pour les paquets distribuables, utilisez plutôt pip et un fichier pyproject.toml approprié.

Flux standard

sys.stdin, sys.stdout et sys.stderr sont des objets de type fichier connectés aux trois flux standard. Vous pouvez les rediriger pour capturer ou supprimer la sortie.

import sys

# Write to stdout (same as print, but more explicit)
sys.stdout.write("Hello, stdout\n")

# Write to stderr (errors and diagnostics)
sys.stderr.write("Warning: something looks off\n")

Un schéma courant dans les scripts consiste à rediriger sys.stdout vers un fichier pour capturer toute la sortie de print() :

import sys

with open("output.log", "w", encoding="utf-8") as log:
    original_stdout = sys.stdout
    sys.stdout = log
    print("This goes to the log file.")
    sys.stdout = original_stdout

print("This goes back to the terminal.")

Attributs sys utiles

Attribut / FonctionCe qu'il retourne
sys.argvListe des arguments de ligne de commande
sys.versionChaîne de version Python
sys.version_infoN-uplet nommé de (major, minor, micro, ...)
sys.platformIdentifiant de plateforme ("linux", "darwin", "win32")
sys.pathChemin de recherche des modules (liste de chaînes)
sys.modulesDictionnaire de tous les modules actuellement importés
sys.stdinFlux d'entrée standard
sys.stdoutFlux de sortie standard
sys.stderrFlux d'erreur standard
sys.exit(code)Quitter l'interpréteur avec le code de statut donné
sys.getrecursionlimit()Profondeur de récursion maximale (défaut 1000)
sys.maxsizeValeur maximale d'un int sur cette plateforme

Combiner os et sys en pratique

Les scripts réels utilisent souvent les deux modules ensemble. Voici un exemple petit mais réaliste : un script qui parcourt un répertoire à la recherche de fichiers .log et affiche un résumé.

import os
import sys

def summarize_logs(directory):
    if not os.path.isdir(directory):
        sys.stderr.write(f"Error: '{directory}' is not a directory.\n")
        sys.exit(1)

    log_files = [
        f for f in os.listdir(directory)
        if f.endswith(".log") and os.path.isfile(os.path.join(directory, f))
    ]

    if not log_files:
        print("No .log files found.")
        return

    print(f"Found {len(log_files)} log file(s) in '{directory}':")
    for name in sorted(log_files):
        full_path = os.path.join(directory, name)
        size = os.path.getsize(full_path)
        print(f"  {name}  ({size} bytes)")

if len(sys.argv) != 2:
    print(f"Usage: python {sys.argv[0]} <directory>")
    sys.exit(1)

summarize_logs(sys.argv[1])

Exécutez-le avec python summarize.py /var/log et il affiche le nom et la taille en octets de chaque fichier .log dans ce répertoire.

os vs pathlib — Lequel utiliser ?

Python 3.4 a introduit pathlib.Path, une alternative orientée objet à os.path. Les deux approches sont correctes ; le choix est surtout une question de préférence stylistique.

TâcheStyle osStyle pathlib
Assembler des cheminsos.path.join(a, b)Path(a) / b
Obtenir le nom de fichieros.path.basename(p)Path(p).name
Obtenir l'extensionos.path.splitext(p)[1]Path(p).suffix
Vérifier l'existenceos.path.exists(p)Path(p).exists()
Lire un fichier texteopen(p).read()Path(p).read_text()
Lister un répertoireos.listdir(p)list(Path(p).iterdir())

pathlib tend à produire un code plus lisible pour les scripts intensifs en manipulation de chemins ; os.path est familier et supporté partout où Python 3 s'exécute. Le module sys n'a pas d'équivalent pathlib — c'est toujours import sys.

Pratique

Pratique
Which function returns the current working directory in Python?
Which function returns the current working directory in Python?
Pratique
What does sys.argv[0] contain when you run a Python script from the command line?
What does sys.argv[0] contain when you run a Python script from the command line?

Chapitres associés

Was this page helpful?