Apprenez en lisant dans l'ordre

os et pathlib — Chemins de fichiers et opérations sur les dossiers

Apprends les modules os.path et pathlib de Python depuis les bases. Construis des chemins indépendants de l'OS, liste et parcours récursivement les dossiers, et décompose les chemins en morceaux avec les objets Path — le tout en pratique.

Deux modules s'occupent des chemins de fichiers et des dossiers — l'ancien os.path et le plus récent et plus lisible pathlib. Cet article parcourt la construction de chemins indépendante de l'OS, le listage de dossier et le parcours récursif, et la décomposition des chemins en morceaux avec les objets Path, dans cet ordre.

os.path — Construire des chemins indépendants de l'OS

Les séparateurs de chemins diffèrent selon l'OS. Windows utilise \ (antislash), tandis que Linux et macOS utilisent /. Coder en dur `"data/sales/2024.csv"` directement dans ton code fonctionne sur Linux et Mac, mais Windows peut mal lire le chemin à l'exécution.

Si tu sépares les parties et les passes à os.path.join("data", "sales", "2024.csv"), Python choisit le bon séparateur à la volée selon l'OS sur lequel il tourne.

os.path.join change les séparateurs selon l'OS
os.path.join( 'data', 'sales', '2024.csv')Linux / Macdata/sales/2024.csvWindowsdata\sales\2024.csv
Le même code Python s'étend à / sur Linux / Mac et \ sur Windows. Ne grave pas les caractères de séparation à la main — c'est l'astuce pour rester portable.
FonctionSignificationExemple
os.path.join(*parts)Joint les chemins avec le séparateur de l'OSjoin('data', 'sales') → 'data/sales'
os.path.exists(p)Si le chemin existeTrue / False
os.path.isfile(p)Si c'est un fichier (pas un dossier)True / False
os.path.isdir(p)Si c'est un dossierTrue / False
os.path.basename(p)Le nom de fichier ou de dossier finalbasename('data/x.csv') → 'x.csv'
os.path.dirname(p)Le chemin parent sans la findirname('data/x.csv') → 'data'
os.path.splitext(p)Sépare l'extensionsplitext('x.csv') → ('x', '.csv')

Construis le chemin vers un fichier CSV de ventes avec os.path et lis son contenu (tu peux voir data/sales/2024_q1.csv et d'autres sous le panneau 📂 Files à gauche).

① Importe os et joins les trois parties de chemin data / sales / 2024_q1.csv en une seule chaîne avec le séparateur de l'OS.

② Affiche le chemin complet tel quel.

③ Ouvre le data/sales/2024_q1.csv préchargé avec open(path, "r") et affiche les trois premières lignes.

(Si tu l'exécutes correctement l'explication apparaît en dessous.)

Éditeur Python

Exécuter le code pour voir le résultat

Pratique 2 — Séparer le nom et l'extension avec basename et splitext

Ne mets pas tout sur une seule ligne — affecte étape par étape dans des variables intermédiaires et sépare le nom de fichier de son extension. basename extrait le nom de fichier final d'un chemin complet, et splitext sépare ce nom en un tuple (nom, extension).

Ne l'écris pas sur une seule ligne — passe par des variables intermédiaires pour extraire le nom de fichier et l'extension.

① Importe os et mets path = "data/sales/2024_q1.csv".

② Extrais le nom de fichier final avec os.path.basename(path), stocke-le dans filename et affiche-le.

③ Utilise os.path.splitext(filename) pour obtenir le tuple (nom, extension), stocke-le dans parts et affiche-le.

Décompose ce tuple dans stem et suffix, et affiche-les comme stem suffix séparés par un espace.

Éditeur Python

Exécuter le code pour voir le résultat

os.listdir et os.walk — Listage de dossier et parcours récursif

Quand tu veux importer le contenu d'un dossier dans Python, utilise os.listdir pour un seul niveau et os.walk pour descendre récursivement dans les sous-dossiers. os.listdir retourne une liste de noms (à la fois fichiers et sous-dossiers) directement à l'intérieur du dossier que tu spécifies, tandis que os.walk parcourt toute la sous-arborescence récursivement et produit des tuples (chemin courant, liste des noms de sous-dossiers, liste des noms de fichiers) un niveau à la fois.

Différence entre os.listdir et os.walk
os.listdirListe des nomsdans le dossier immédiatos.walkParcourir récursivementchaque niveau
os.listdir te donne uniquement les noms immédiats ; os.walk descend récursivement à travers chaque niveau. Choisis selon la profondeur dont tu as besoin.
import os

# Un niveau : noms directement sous 'data'
print(os.listdir("data"))
# → ['sales', 'inventory']

# Récursif : parcourir tout sous 'data'
for dirpath, dirnames, filenames in os.walk("data"):
    print(dirpath, filenames)
# → data ['sales', 'inventory'] []
#    data/sales [] ['2024_q1.csv', '2024_q2.csv']
#    data/inventory [] ['items.json']

Affiche ce qu'il y a dans le répertoire `data/` de deux façons — d'abord le niveau immédiat, puis récursivement.

① Importe os.

② Utilise os.listdir("data") pour lister les noms directement sous `data/` dans l'ordre trié (enveloppe avec sorted pour garder l'ordre stable).

③ Utilise os.walk("data") pour parcourir data/ récursivement et afficher une ligne par niveau montrant (chemin courant, liste des noms de fichiers) (enveloppe la liste de noms de fichiers avec sorted aussi).

Éditeur Python

Exécuter le code pour voir le résultat

glob — Filtrage par motif pour collecter des fichiers

Quand tu veux saisir uniquement les fichiers qui correspondent à une condition — comme uniquement les fichiers avec l'extension `.csv` — le module glob est le chemin le plus court. Écris la cible comme un motif en utilisant des jokers comme * (n'importe quelle chaîne) ou ** (n'importe quelle profondeur) et tu récupères une liste de chemins correspondants.

Jokers de glob
*N'importe quelle chaîne dansle même niveau**Traverse n'importe quelle profondeur(recursive=True)
* correspond à n'importe quelle chaîne dans le même niveau, ** traverse n'importe quel nombre de niveaux (nécessite recursive=True).
import glob

# Fichiers CSV directement sous data/sales
print(glob.glob("data/sales/*.csv"))
# → ['data/sales/2024_q1.csv', 'data/sales/2024_q2.csv']

# Recherche récursive sous data (** + recursive=True)
print(glob.glob("data/**/*.csv", recursive=True))
# → ['data/sales/2024_q1.csv', 'data/sales/2024_q2.csv']

Le joker ** de glob s'associe à recursive=True

Le double astérisque dans glob.glob("data/**/*.csv") est un joker qui traverse n'importe quel nombre de niveaux. Mais sans recursive=True, il se comporte comme un * ordinaire et ne trouvera rien dans les dossiers plus profonds. Passe toujours cet argument quand tu veux une recherche récursive.

Récupère les fichiers CSV dans `data/sales/` d'un seul coup avec glob.

① Importe glob.

② Utilise glob.glob("data/sales/*.csv") pour saisir les CSV sous sales, trie avec sorted et stocke le résultat dans csv_files.

③ Affiche chaque chemin un par un.

④ Affiche le nombre sous la forme Found files: ◯.

Éditeur Python

Exécuter le code pour voir le résultat

pathlib.Path — Opérations de chemin orientées objet

Alors que os.path était une bibliothèque qui gère les chemins comme des chaînes, depuis Python 3.4 l'approche recommandée est pathlib.Path, qui traite les chemins eux-mêmes comme des objets. Construis-en un avec Path("data/sales/2024_q1.csv") et tu peux accéder à chaque partie via des attributs comme .parent pour le dossier parent, .name pour le morceau final, .stem pour le nom sans extension, et .suffix pour l'extension.

Attributs de l'objet Path
Path('data/sales/2024_q1.csv').parentPath('data/sales').name'2024_q1.csv'.stem'2024_q1'.suffix'.csv'
Depuis un seul Path tu peux extraire chaque partie avec .parent / .name / .stem / .suffix. Plus facile à lire qu'appeler os.path.dirname / basename / splitext séparément.
from pathlib import Path

p = Path("data") / "sales" / "2024_q1.csv"   # Joindre avec l'opérateur /
print(p)               # data/sales/2024_q1.csv
print(p.parent)        # data/sales
print(p.name)          # 2024_q1.csv
print(p.stem)          # 2024_q1
print(p.suffix)        # .csv
print(p.exists())      # True

# Lire le contenu (un wrapper autour de with open)
print(p.read_text())   # Contenu CSV

# Lister les sous-dossiers (équivalent à os.walk)
for sub in Path("data").rglob("*.csv"):
    print(sub)

`os.path` est basé sur les chaînes, `pathlib.Path` est basé sur les objets — ils offrent les mêmes opérations. Le tableau ci-dessous fait correspondre chaque tâche entre eux.

Ce que tu veuxStyle os.pathStyle pathlib
Joindreos.path.join('data', 'x.csv')Path('data') / 'x.csv'
Dossier parentos.path.dirname(p)p.parent
Nom de fichieros.path.basename(p)p.name
Nom sans extensionUtiliser os.path.splitext(p)[0]p.stem
Extensionos.path.splitext(p)[1]p.suffix
Vérification d'existenceos.path.exists(p)p.exists()
Recherche récursiveglob.glob('**/*.csv', recursive=True)Path('.').rglob('*.csv')
Lecturewith open(p) as f: f.read()p.read_text()

Choisis pathlib pour le nouveau code

Pathlib est recommandé pour le nouveau code. Quand des API de bibliothèques plus anciennes exigent des chemins en chaînes (certains pilotes de BD, par exemple), convertis avec str(p). os.path n'est pas près de partir, donc connaître les deux correspondances te garde à l'aise pour lire aussi le code legacy.

Utilise pathlib.Path pour gérer un CSV de ventes. Au lieu de concaténer des chaînes directement, obtiens le même résultat à travers l'opérateur et les attributs de l'objet Path.

① Importe la classe Path depuis pathlib.

② Construis un seul objet Path à partir des trois parties data / sales / 2024_q1.csv en utilisant l'opérateur de jointure de Path (le remplaçant de os.path.join).

③ Extrais le nom sans extension et l'extension depuis le Path via accès par attribut, et affiche-les séparés par un espace.

④ Utilise une méthode Path pour lire le contenu du fichier comme une seule chaîne et l'afficher (la façon qui ne nécessite pas with open(...)).

Éditeur Python

Exécuter le code pour voir le résultat
QUIZ

Vérification des connaissances

Répondez à chaque question une par une.

Question 1Quelle est la façon recommandée de construire des chemins qui ne cassent pas sur Windows ou Linux ?

Question 2Lequel des suivants convient le mieux pour parcourir chaque niveau d'un dossier récursivement ?

Question 3Étant donné p = Path("data/sales/2024_q1.csv"), quelle est la valeur de p.stem ?