Python & AI Tutorials Logo
Programmation Python

29. Interagir avec le système d’exploitation : sys et os

Les programmes Python n’existent pas en vase clos : ils s’exécutent sur un système d’exploitation qui gère les fichiers, les répertoires, les paramètres d’environnement, et la manière dont les programmes démarrent et communiquent. Les modules sys et os fournissent des outils pour interagir avec cet environnement, en permettant à vos programmes d’accepter des arguments en ligne de commande, de lire des variables d’environnement, de naviguer dans le système de fichiers, et de créer ou supprimer des répertoires.

Comprendre ces modules transforme vos scripts Python : au lieu d’un code isolé, vous obtenez des programmes capables de s’intégrer au système au sens large, de répondre aux entrées utilisateur au démarrage, et de gérer des fichiers et des dossiers par programmation.

29.1) Arguments en ligne de commande et utilisation de sys.argv

Lorsque vous exécutez un script Python depuis le terminal ou l’invite de commandes, vous pouvez lui passer des informations supplémentaires : ce sont les arguments en ligne de commande(command-line arguments). Par exemple :

bash
python greet.py Alice 25

Ici, greet.py est le nom du script, et Alice et 25 sont des arguments passés au programme. Le module sys donne accès à ces arguments via sys.argv, une liste contenant le nom du script et tous les arguments sous forme de chaînes de caractères.

29.1.1) Qu’est-ce que sys.argv ?

sys.argv est une liste dans laquelle :

  • sys.argv[0] est toujours le nom du script exécuté
  • sys.argv[1], sys.argv[2], etc., sont les arguments passés après le nom du script
  • Tous les éléments sont des chaînes, même s’ils ressemblent à des nombres

Créons un script simple pour voir comment cela fonctionne :

python
# show_args.py
import sys
 
print("Script name:", sys.argv[0])
print("Number of arguments:", len(sys.argv))
print("All arguments:", sys.argv)

Si vous exécutez ce script avec :

bash
python show_args.py hello world 123

Output:

Script name: show_args.py
Number of arguments: 4
All arguments: ['show_args.py', 'hello', 'world', '123']

Remarquez que sys.argv contient 4 éléments : le nom du script plus trois arguments. Le nombre 123 est stocké comme la chaîne '123', et non comme un entier.

29.1.2) Utiliser des arguments en ligne de commande dans des programmes

Les arguments en ligne de commande permettent aux utilisateurs de personnaliser le comportement d’un programme sans modifier le code. Voici un programme de salutation qui utilise le premier argument comme nom :

python
# greet.py
import sys
 
if len(sys.argv) < 2:
    print("Usage: python greet.py <name>")
    sys.exit(1)  # Quitter avec un code d’erreur
 
name = sys.argv[1]
print(f"Hello, {name}!")

En l’exécutant :

bash
python greet.py Alice

Output:

Hello, Alice!

Si vous oubliez de fournir un nom :

bash
python greet.py

Output:

Usage: python greet.py <name>

Le programme vérifie si suffisamment d’arguments ont été fournis. Si ce n’est pas le cas, il affiche un message d’usage et se termine avec sys.exit(1). Le nombre 1 est un code de sortie(exit code) : par convention, 0 signifie succès et des valeurs non nulles indiquent des erreurs. Cela aide d’autres programmes ou scripts à détecter si votre programme s’est exécuté correctement.

29.1.3) Convertir des arguments vers d’autres types

Puisque tous les arguments arrivent sous forme de chaînes, vous devez souvent les convertir. Voici un programme qui calcule l’aire d’un rectangle :

python
# area.py
import sys
 
if len(sys.argv) < 3:
    print("Usage: python area.py <width> <height>")
    sys.exit(1)
 
try:
    width = float(sys.argv[1])
    height = float(sys.argv[2])
except ValueError:
    print("Error: Width and height must be numbers")
    sys.exit(1)
 
area = width * height
print(f"Area: {area}")

En l’exécutant :

bash
python area.py 5.5 3.2

Output:

Area: 17.6

Si l’utilisateur fournit une entrée invalide :

bash
python area.py five three

Output:

Error: Width and height must be numbers

Le bloc try-except (du chapitre 25) gère les erreurs de conversion de manière élégante, en fournissant un retour utile plutôt que de planter avec une traceback.

Utilisateur exécute : python script.py arg1 arg2

Python crée la liste sys.argv

sys.argv[0] = 'script.py'

sys.argv[1] = 'arg1'

sys.argv[2] = 'arg2'

Le script accède à sys.argv

Traiter les arguments comme des chaînes

Convertir les types si nécessaire

Utiliser les valeurs dans la logique du programme

29.2) Obtenir des informations sur l’interpréteur et l’exécution avec sys

Le module sys fournit des informations sur l’interpréteur Python lui-même et sur l’environnement d’exécution. C’est utile pour le débogage(debugging), la journalisation(logging) ou l’écriture de code qui s’adapte à différentes versions de Python ou plateformes.

29.2.1) Informations sur la version de Python

sys.version et sys.version_info vous indiquent quelle version de Python exécute votre code :

python
import sys
 
print("Python version string:", sys.version)
print("Version info:", sys.version_info)
print(f"Major version: {sys.version_info.major}")
print(f"Minor version: {sys.version_info.minor}")

Output (example):

Python version string: 3.11.4 (main, Jul  5 2023, 13:45:01) [GCC 11.2.0]
Version info: sys.version_info(major=3, minor=11, micro=4, releaselevel='final', serial=0)
Major version: 3
Minor version: 11

sys.version est une chaîne lisible par un humain, tandis que sys.version_info est un tuple nommé que vous pouvez comparer par programmation :

python
import sys
 
if sys.version_info < (3, 8):
    print("This program requires Python 3.8 or higher")
    sys.exit(1)
 
print("Python version is compatible")

Cela garantit que votre programme ne s’exécute que sur des versions de Python prises en charge.

29.2.2) Informations sur la plateforme

sys.platform identifie le système d’exploitation :

python
import sys
 
print("Platform:", sys.platform)
 
if sys.platform == "win32":
    print("Running on Windows")
elif sys.platform == "darwin":
    print("Running on macOS")
elif sys.platform.startswith("linux"):
    print("Running on Linux")
else:
    print("Running on another platform")

Output (on Linux):

Platform: linux
Running on Linux

Cela vous permet d’écrire du code spécifique à une plateforme lorsque c’est nécessaire, par exemple en utilisant des chemins de fichiers ou des commandes système différents.

29.2.3) Chemin de recherche des modules

sys.path est une liste de répertoires que Python parcourt lorsqu’il importe des modules :

python
import sys
 
print("Module search paths:")
for path in sys.path:
    print(f"  {path}")

Output (example):

Module search paths:
  /home/user/projects
  /usr/lib/python3.11
  /usr/lib/python3.11/lib-dynload
  /home/user/.local/lib/python3.11/site-packages

La première entrée est généralement le répertoire contenant votre script. Python recherche ces chemins dans l’ordre lorsque vous utilisez import. Comprendre sys.path aide à déboguer des erreurs d’import ou à ajouter des répertoires de modules personnalisés.

29.2.4) Quitter des programmes avec des codes de sortie

Nous avons vu sys.exit() utilisé pour arrêter des programmes. Vous pouvez passer un code de sortie pour indiquer un succès ou un échec :

python
import sys
 
def process_data(filename):
    try:
        with open(filename) as f:
            data = f.read()
        # Traiter les données...
        return True
    except FileNotFoundError:
        print(f"Error: File '{filename}' not found", file=sys.stderr)
        return False
 
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python script.py <filename>", file=sys.stderr)
        sys.exit(1)
    
    success = process_data(sys.argv[1])
    sys.exit(0 if success else 1)

Les codes de sortie suivent les conventions Unix :

  • 0 signifie succès
  • Des valeurs non nulles indiquent différents types d’erreurs
  • D’autres programmes peuvent vérifier ces codes pour déterminer si votre programme a réussi

29.3) Accéder aux variables d’environnement avec os

Les variables d’environnement(environment variables) sont des paires clé-valeur définies par le système d’exploitation ou l’utilisateur, que les programmes peuvent lire. Elles servent à la configuration, au stockage de chemins, de clés d’API, et d’autres paramètres qui ne devraient pas être codés en dur.

29.3.1) Lire des variables d’environnement

Le module os fournit os.environ, un objet de type dictionnaire contenant toutes les variables d’environnement :

python
import os
 
# Obtenir une variable d’environnement spécifique
home = os.environ.get('HOME')  # Sur Unix/Linux/macOS
print(f"Home directory: {home}")
 
# Renvoie None si la variable n’existe pas
api_key = os.environ.get('MY_API_KEY')
print(f"API key: {api_key}")

Output (on Linux):

Home directory: /home/alice
API key: None

Vous pouvez fournir une valeur par défaut :

python
import os
 
# Obtenir une variable d’environnement avec une valeur par défaut
log_level = os.environ.get('LOG_LEVEL', 'INFO')
print(f"Log level: {log_level}")

Output (if LOG_LEVEL not set):

Log level: INFO

29.3.2) Variables d’environnement courantes

Différents systèmes d’exploitation fournissent des variables d’environnement standard :

python
import os
 
# Variables multiplateformes
print("Path:", os.environ.get('PATH'))
 
# Unix/Linux/macOS
print("User:", os.environ.get('USER'))
print("Home:", os.environ.get('HOME'))
print("Shell:", os.environ.get('SHELL'))
 
# Windows
print("User", os.environ.get('USERNAME'))
print("User Profile:", os.environ.get('USERPROFILE'))
print("Temp:", os.environ.get('TEMP'))

PATH est particulièrement importante : elle liste les répertoires dans lesquels le système recherche des programmes exécutables. Lorsque vous tapez une commande comme python, le système recherche dans ces répertoires.

29.3.3) Définir des variables d’environnement

Vous pouvez modifier des variables d’environnement pour votre programme et tous les sous-processus qu’il crée :

python
import os
 
# Définir une variable d’environnement
os.environ['MY_CONFIG'] = 'production'
 
# La relire
print(os.environ.get('MY_CONFIG'))  # Output: production
 
# Supprimer une variable d’environnement
del os.environ['MY_CONFIG']

Important : les modifications de os.environ n’affectent que le processus Python courant et les programmes qu’il lance. Elles ne persistent pas après la fin de votre programme et n’affectent pas les autres programmes.

29.4) Travailler avec les chemins de fichiers et les répertoires (os.path, os.getcwd)

Gérer correctement les chemins de fichiers est crucial pour les programmes qui travaillent avec des fichiers. Les modules os et os.path fournissent des outils pour construire, manipuler et interroger des chemins de manière indépendante de la plateforme.

29.4.1) Obtenir le répertoire de travail actuel

Le répertoire de travail actuel(current working directory) (CWD) est le dossier que votre programme considère comme point de départ pour les chemins relatifs :

python
import os
 
cwd = os.getcwd()
print(f"Current working directory: {cwd}")

Output (example):

Current working directory: /home/alice/projects/myapp

Lorsque vous ouvrez un fichier avec un chemin relatif comme 'data.txt', Python cherche dans le répertoire de travail actuel. Comprendre le CWD aide à déboguer des erreurs « fichier introuvable ».

29.4.2) Changer le répertoire actuel

Vous pouvez changer le répertoire de travail avec os.chdir() :

python
import os
 
original = os.getcwd()
print("Original directory:", original)
 
# Changer vers un autre répertoire
os.chdir('/tmp')
print("New directory:", os.getcwd())
 
# Revenir en arrière
os.chdir(original)
print("Back to:", os.getcwd())

Output:

Original directory: /home/alice/projects
New directory: /tmp
Back to: /home/alice/projects

Note : au chapitre 28, vous avez appris contextlib.chdir(), qui restaure automatiquement le répertoire original. Pour des changements de répertoire simples, privilégiez l’utilisation du gestionnaire de contexte :

python
from contextlib import chdir
 
with chdir('/tmp'):
    print("Temporarily in:", os.getcwd())
# Automatically restored

Cela garantit que le répertoire est toujours restauré, même si une erreur se produit.

29.4.3) Construire des chemins avec os.path.join()

Différents systèmes d’exploitation utilisent différents séparateurs de chemin :

  • Unix/Linux/macOS : / (barre oblique)
  • Windows : \ (barre oblique inversée)

os.path.join() construit correctement les chemins pour la plateforme actuelle :

python
import os
 
# Construire un chemin vers un fichier dans un sous-répertoire
data_dir = 'data'
filename = 'users.txt'
filepath = os.path.join(data_dir, filename)
 
print(f"File path: {filepath}")

Output (on Unix/Linux/macOS):

File path: data/users.txt

Output (on Windows):

File path: data\users.txt

Vous pouvez assembler plusieurs composants :

python
import os
 
base = '/home/alice'
project = 'myapp'
subdir = 'data'
file = 'config.json'
 
full_path = os.path.join(base, project, subdir, file)
print(full_path)  # Output: /home/alice/myapp/data/config.json

L’utilisation de os.path.join() rend votre code portable entre systèmes d’exploitation.

29.4.4) Vérifier si des chemins existent

Avant de travailler avec des fichiers ou des répertoires, vérifiez s’ils existent :

python
import os
 
path = 'data.txt'
 
if os.path.exists(path):
    print(f"'{path}' exists")
else:
    print(f"'{path}' does not exist")

Vous pouvez aussi vérifier spécifiquement s’il s’agit de fichiers ou de répertoires :

python
import os
 
path = 'mydir'
 
if os.path.isfile(path):
    print(f"'{path}' is a file")
elif os.path.isdir(path):
    print(f"'{path}' is a directory")
elif os.path.exists(path):
    print(f"'{path}' exists but is neither a file nor directory")
else:
    print(f"'{path}' does not exist")

Ces vérifications évitent des erreurs lorsqu’on tente d’ouvrir des fichiers inexistants ou de lister des répertoires inexistants.

29.4.5) Obtenir des chemins absolus

os.path.abspath() convertit des chemins relatifs en chemins absolus :

python
import os
 
relative_path = 'data/users.txt'
absolute_path = os.path.abspath(relative_path)
 
print(f"Relative: {relative_path}")
print(f"Absolute: {absolute_path}")

Output (example):

Relative: data/users.txt
Absolute: /home/alice/projects/myapp/data/users.txt

C’est utile pour la journalisation, les messages d’erreur, ou lorsque vous devez connaître l’emplacement exact d’un fichier.

29.4.6) Découper des chemins en composants

os.path.split() sépare un chemin en répertoire et nom de fichier :

python
import os
 
path = '/home/alice/projects/data.txt'
directory, filename = os.path.split(path)
 
print(f"Directory: {directory}")
print(f"Filename: {filename}")

Output:

Directory: /home/alice/projects
Filename: data.txt

os.path.basename() récupère uniquement le nom de fichier, et os.path.dirname() récupère uniquement le répertoire :

python
import os
 
path = '/home/alice/projects/data.txt'
 
print(f"Basename: {os.path.basename(path)}")  # Output: data.txt
print(f"Dirname: {os.path.dirname(path)}")    # Output: /home/alice/projects

29.4.7) Découper les extensions de fichier

os.path.splitext() sépare le nom de fichier de son extension :

python
import os
 
filename = 'report.pdf'
name, extension = os.path.splitext(filename)
 
print(f"Name: {name}")        # Output: report
print(f"Extension: {extension}")  # Output: .pdf

C’est utile pour traiter des fichiers selon leur type :

python
import os
 
files = ['data.csv', 'image.png', 'document.txt', 'script.py']
 
for file in files:
    name, ext = os.path.splitext(file)
    if ext == '.csv':
        print(f"Process CSV file: {file}")
    elif ext == '.png':
        print(f"Process image file: {file}")

Output:

Process CSV file: data.csv
Process image file: image.png

29.5) Lister, créer et supprimer des fichiers et des répertoires

Le module os fournit des fonctions pour manipuler le système de fichiers : lister le contenu des répertoires, créer de nouveaux répertoires, et supprimer des fichiers et des dossiers.

29.5.1) Lister le contenu d’un répertoire

os.listdir() renvoie une liste de tous les éléments d’un répertoire :

python
import os
 
# Lister le contenu du répertoire courant
contents = os.listdir('.')
print("Current directory contents:")
for item in contents:
    print(f"  {item}")

Output (example):

Current directory contents:
  script.py
  data.txt
  mydir
  README.md

La liste inclut à la fois des fichiers et des répertoires. Pour les distinguer :

python
import os
 
contents = os.listdir('.')
print("Files:")
for item in contents:
    if os.path.isfile(item):
        print(f"  {item}")
 
print("\nDirectories:")
for item in contents:
    if os.path.isdir(item):
        print(f"  {item}")

Output:

Files:
  script.py
  data.txt
  README.md
 
Directories:
  mydir

29.5.2) Créer des répertoires

os.mkdir() crée un seul répertoire :

python
import os
 
new_dir = 'output'
 
if not os.path.exists(new_dir):
    os.mkdir(new_dir)
    print(f"Created directory: {new_dir}")
else:
    print(f"Directory already exists: {new_dir}")

Output:

Created directory: output

Important : os.mkdir() échoue si le répertoire parent n’existe pas. Par exemple, tenter de créer 'data/output' lorsque 'data' n’existe pas lèvera une erreur.

os.makedirs() crée tous les répertoires parents nécessaires :

python
import os
 
nested_dir = 'data/processed/2024'
 
if not os.path.exists(nested_dir):
    os.makedirs(nested_dir)
    print(f"Created directory structure: {nested_dir}")

Output:

Created directory structure: data/processed/2024

Cela crée data, puis data/processed, puis data/processed/2024 s’ils n’existent pas.

29.5.3) Supprimer des fichiers

os.remove() supprime un fichier :

python
import os
 
filename = 'temp.txt'
 
# Créer un fichier temporaire
with open(filename, 'w') as f:
    f.write('Temporary data')
 
print(f"File exists: {os.path.exists(filename)}")  # Output: True
 
# Supprimer le fichier
os.remove(filename)
print(f"File exists: {os.path.exists(filename)}")  # Output: False

Avertissement : os.remove() supprime définitivement les fichiers ; ils ne vont pas dans une corbeille.

29.5.4) Supprimer des répertoires

os.rmdir() supprime un répertoire vide :

python
import os
 
directory = 'empty_dir'
 
# Créer puis supprimer un répertoire vide
os.mkdir(directory)
print(f"Created: {directory}")
 
os.rmdir(directory)
print(f"Removed: {directory}")

os.rmdir() échoue si le répertoire contient des fichiers. Pour supprimer un répertoire et tout son contenu, vous devez d’abord supprimer les fichiers :

python
import os
 
def remove_directory_contents(directory):
    """Supprimer tous les fichiers d’un répertoire, puis supprimer le répertoire.
    
    Remarque : échoue si le répertoire contient des sous-répertoires.
    """
    if not os.path.exists(directory):
        print(f"Directory does not exist: {directory}")
        return
    
    # Supprimer tous les fichiers du répertoire
    for item in os.listdir(directory):
        item_path = os.path.join(directory, item)
        if os.path.isfile(item_path):
            os.remove(item_path)
            print(f"Removed file: {item_path}")
    
    # Supprimer le répertoire désormais vide
    os.rmdir(directory)
    print(f"Removed directory: {directory}")
 
# Exemple d’utilisation
test_dir = 'test_data'
os.makedirs(test_dir, exist_ok=True)
 
# Créer quelques fichiers de test
with open(os.path.join(test_dir, 'file1.txt'), 'w') as f:
    f.write('test')
with open(os.path.join(test_dir, 'file2.txt'), 'w') as f:
    f.write('test')
 
# Tout supprimer
remove_directory_contents(test_dir)

Output:

Removed file: test_data/file1.txt
Removed file: test_data/file2.txt
Removed directory: test_data

Note : pour une suppression de répertoire plus complexe (y compris les sous-répertoires), le module shutil de Python fournit shutil.rmtree(), mais cela dépasse notre périmètre actuel.

29.5.5) Renommer des fichiers et des répertoires

os.rename() renomme ou déplace des fichiers et des répertoires :

python
import os
 
# Renommer un fichier
old_name = 'draft.txt'
new_name = 'final.txt'
 
# Créer un fichier de test
with open(old_name, 'w') as f:
    f.write('content')
 
os.rename(old_name, new_name)
print(f"Renamed '{old_name}' to '{new_name}'")

Vous pouvez aussi déplacer des fichiers vers d’autres répertoires :

python
import os
 
# Créer des répertoires et un fichier
os.makedirs('source', exist_ok=True)
os.makedirs('destination', exist_ok=True)
 
with open('source/file.txt', 'w') as f:
    f.write('content')
 
# Déplacer le fichier vers un autre répertoire
os.rename('source/file.txt', 'destination/file.txt')
print("Moved file to destination directory")

Les modules sys et os donnent à vos programmes Python la capacité d’interagir avec le système d’exploitation, d’accepter des entrées en ligne de commande, de lire la configuration, et de gérer des fichiers et des répertoires. Ces capacités transforment des scripts simples en outils puissants en ligne de commande qui s’intègrent de manière transparente à l’environnement système au sens large.


© 2025. Primesoft Co., Ltd.
support@primesoft.ai