
Le module pathlib représente un chemin de fichier comme un objet Path, avec des méthodes lisibles pour tester, composer, lire et parcourir l'arborescence. Fini d'empiler les appels os.path.join, os.path.exists et os.path.splitext : une seule classe Path remplace une dizaine de fonctions dispersées, avec l'opérateur / pour assembler les chemins comme on lirait une phrase. Ce guide couvre la composition de chemins, les tests (exists, is_file), la création de dossiers, la lecture-écriture de texte, le parcours avec glob et rglob, et le comparatif avec l'ancien os.path.
Il s'adresse aux développeurs qui écrivent des scripts DevOps, manipulent des fichiers de configuration ou traitent des logs, et veulent un code plus court et plus portable entre Linux, macOS et Windows. Les exemples ont été exécutés avec Python 3.12.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Composer un chemin avec
Pathet l'opérateur/. - Tester l'existence et la nature d'un chemin (
exists,is_file,is_dir). - Créer des dossiers et lire-écrire du texte en une ligne.
- Parcourir une arborescence avec
iterdir,globetrglob. - Extraire les composants d'un chemin (
name,stem,suffix,parent). - Comprendre pourquoi préférer pathlib à
os.path.
Créer un chemin avec Path
Section intitulée « Créer un chemin avec Path »Tout commence par la classe Path, importée depuis le module pathlib de la bibliothèque standard. On lui passe un chemin sous forme de texte, et elle renvoie un objet chemin que l'on manipule ensuite par méthodes. Sur Linux et macOS, l'objet concret est une PosixPath ; le code, lui, reste identique quelle que soit la plateforme.
from pathlib import Path
base = Path("projet")print(base)print(type(base).__name__)projetPosixPathL'atout central de pathlib est l'opérateur /, détourné pour assembler des chemins. Chaque / ajoute un segment, sans se soucier du séparateur de dossier propre au système d'exploitation. Le résultat se lit comme le chemin réel, ce qui rend le code immédiatement compréhensible.
config = Path("projet") / "config" / "app.toml"print(config)projet/config/app.tomlSe repérer avec cwd et home
Section intitulée « Se repérer avec cwd et home »Deux méthodes de classe donnent des points d'ancrage courants. Path.cwd() renvoie le répertoire de travail courant, c'est-à-dire le dossier depuis lequel le script a été lancé. Path.home() renvoie le dossier personnel de l'utilisateur, l'équivalent de ~ sur un terminal. Ces deux points de départ évitent de coder en dur un chemin absolu qui casserait sur une autre machine.
from pathlib import Path
print("Répertoire courant :", Path.cwd().is_dir())print("Dossier personnel :", Path.home().is_dir())Répertoire courant : TrueDossier personnel : TrueÀ partir de ces ancres, on compose vers la cible : Path.home() / ".config" / "monoutil" pointe vers le dossier de configuration de l'utilisateur, sur n'importe quel système Unix.
Tester un chemin avant d'agir
Section intitulée « Tester un chemin avant d'agir »Avant de lire ou d'écrire, on vérifie ce qui existe vraiment. Trois méthodes couvrent l'essentiel : .exists() dit si le chemin correspond à quelque chose, .is_file() confirme qu'il s'agit d'un fichier, et .is_dir() qu'il s'agit d'un dossier. Ces tests ne lèvent jamais d'exception si le chemin est absent : ils renvoient simplement False.
from pathlib import Path
notes = Path("projet/notes.txt")print("existe :", notes.exists())print("est un fichier :", notes.is_file())print("est un dossier :", notes.is_dir())print("projet est un dossier :", Path("projet").is_dir())existe : Trueest un fichier : Trueest un dossier : Falseprojet est un dossier : TrueCes vérifications servent de garde-fous dans un script : tester is_file() avant d'ouvrir un fichier évite un plantage brutal quand le fichier attendu n'a pas été généré.
Créer des dossiers avec mkdir
Section intitulée « Créer des dossiers avec mkdir »Pour créer un dossier, .mkdir() suffit, mais ses deux options changent tout dans un script robuste. parents=True crée au passage tous les dossiers parents manquants, comme mkdir -p en shell. exist_ok=True évite l'erreur FileExistsError si le dossier est déjà là, ce qui rend le script rejouable sans planter au second lancement.
from pathlib import Path
logs = Path("projet/data/logs")logs.mkdir(parents=True, exist_ok=True)print("dossier créé :", logs.is_dir())
# Rejouer la même ligne ne lève aucune erreurlogs.mkdir(parents=True, exist_ok=True)print("rejeu sans erreur : OK")dossier créé : Truerejeu sans erreur : OKLire et écrire du texte en une ligne
Section intitulée « Lire et écrire du texte en une ligne »pathlib intègre deux raccourcis qui remplacent l'ouverture manuelle d'un fichier. .write_text() écrit une chaîne complète dans le fichier, en le créant ou en l'écrasant. .read_text() renvoie tout le contenu du fichier sous forme de chaîne. Les deux gèrent l'ouverture et la fermeture du fichier pour vous. Précisez toujours encoding="utf-8" pour un comportement identique sur toutes les plateformes.
from pathlib import Path
notes = Path("projet/notes.txt")notes.write_text("première ligne\nseconde ligne\n", encoding="utf-8")
contenu = notes.read_text(encoding="utf-8")print(repr(contenu))'première ligne\nseconde ligne\n'Ces méthodes sont parfaites pour des fichiers courts : une configuration, un petit rapport, un marqueur d'état. Pour un gros fichier que l'on traite ligne par ligne, ou pour un accès en flux, l'approche classique avec open() reste préférable, détaillée dans le guide lire et écrire un fichier.
Parcourir une arborescence
Section intitulée « Parcourir une arborescence »Trois méthodes explorent le contenu d'un dossier, du plus simple au plus puissant. .iterdir() liste le contenu direct d'un dossier, fichiers et sous-dossiers confondus, sans descendre plus bas.
from pathlib import Path
base = Path("projet")for entree in sorted(base.iterdir()): nature = "dossier" if entree.is_dir() else "fichier" print(entree, "->", nature)projet/config -> dossierprojet/data -> dossierprojet/notes.txt -> fichierprojet/rapport.md -> fichier.glob() filtre par motif dans le dossier courant : *.txt ne retient que les fichiers texte. L'astérisque remplace n'importe quelle suite de caractères, mais ne traverse pas les sous-dossiers.
for fichier in sorted(base.glob("*.txt")): print(fichier)projet/notes.txt.rglob() applique le même motif de façon récursive, en descendant dans toute l'arborescence. C'est l'outil idéal pour retrouver tous les fichiers d'un type donné, où qu'ils se trouvent.
for fichier in sorted(base.rglob("*.csv")): print(fichier)projet/data/mesures.csvDécomposer un chemin
Section intitulée « Décomposer un chemin »Un objet Path expose ses parties sous forme d'attributs, sans manipulation de chaîne. .name est le nom du fichier complet, .stem le nom sans extension, .suffix l'extension, .parent le dossier contenant, et .parts l'ensemble des segments sous forme de tuple.
from pathlib import Path
p = Path("projet/config/app.toml")print("name :", p.name)print("stem :", p.stem)print("suffix :", p.suffix)print("parent :", p.parent)print("parts :", p.parts)name : app.tomlstem : appsuffix : .tomlparent : projet/configparts : ('projet', 'config', 'app.toml')Ces attributs simplifient énormément le traitement par lot : renommer une série de fichiers en changeant l'extension, regrouper des logs par dossier parent, ou trier des documents par nom de base devient trivial.
Normaliser avec resolve
Section intitulée « Normaliser avec resolve »Un chemin relatif comme projet/../projet/notes.txt contient des détours inutiles. .resolve() le transforme en chemin absolu normalisé : elle supprime les .., résout les liens symboliques et préfixe le répertoire courant. C'est indispensable pour comparer deux chemins de façon fiable ou pour journaliser un emplacement sans ambiguïté.
from pathlib import Path
rel = Path("projet/../projet/notes.txt")absolu = rel.resolve()print("nom :", absolu.name)print("est absolu :", absolu.is_absolute())nom : notes.txtest absolu : TrueRenommer et supprimer
Section intitulée « Renommer et supprimer »Deux méthodes gèrent le cycle de vie d'un fichier. .rename() déplace ou renomme un chemin vers une nouvelle cible. .unlink() supprime un fichier ; son option missing_ok=True évite l'erreur si le fichier a déjà disparu, ce qui sécurise un nettoyage rejouable.
from pathlib import Path
base = Path("projet")ancien = base / "rapport.md"nouveau = base / "rapport-2026.md"ancien.rename(nouveau)print("ancien existe :", ancien.exists())print("nouveau existe :", nouveau.exists())
temp = base / "temporaire.log"temp.write_text("jetable", encoding="utf-8")temp.unlink()print("après suppression :", temp.exists())temp.unlink(missing_ok=True) # ne lève rien, le fichier est déjà partiprint("nettoyage idempotent : OK")ancien existe : Falsenouveau existe : Trueaprès suppression : Falsenettoyage idempotent : OKPourquoi préférer pathlib à os.path
Section intitulée « Pourquoi préférer pathlib à os.path »L'ancienne façon de faire reposait sur le module os.path, une collection de fonctions qui prennent des chaînes et en renvoient. Le code s'y lit de l'intérieur vers l'extérieur, en imbriquant les appels, ce qui devient vite illisible. pathlib remplace tout cela par des méthodes chaînées sur un objet, dans l'ordre naturel de lecture.
Le tableau suivant met les deux approches côte à côte sur les opérations les plus courantes. La colonne de droite se lit sans effort, et un seul import suffit là où os.path en demandait plusieurs.
| Opération | os.path (ancien) | pathlib (moderne) |
|---|---|---|
| Composer | os.path.join("projet", "app.toml") | Path("projet") / "app.toml" |
| Extension | os.path.splitext(chemin)[1] | chemin.suffix |
| Nom du fichier | os.path.basename(chemin) | chemin.name |
| Dossier parent | os.path.dirname(chemin) | chemin.parent |
| Existe | os.path.exists(chemin) | chemin.exists() |
| Chemin absolu | os.path.abspath(chemin) | chemin.resolve() |
Ce même traitement, exécuté dans les deux styles, produit un résultat identique. La différence n'est pas dans la sortie, mais dans la lisibilité et la maintenabilité du code.
import os.pathfrom pathlib import Path
chemin_os = os.path.join("projet", "config", "app.toml")print("os.path :", os.path.basename(chemin_os), os.path.splitext(chemin_os)[1])
chemin = Path("projet") / "config" / "app.toml"print("pathlib :", chemin.name, chemin.suffix)os.path : app.toml .tomlpathlib : app.toml .tomlDepuis Python 3.6, la plupart des fonctions de la bibliothèque standard qui attendent un chemin acceptent directement un objet Path. Il n'y a donc aucune raison de rester sur os.path pour du code neuf : pathlib est la recommandation officielle, plus sûr entre systèmes et nettement plus agréable à relire.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À retenir
Section intitulée « À retenir »Pathreprésente un chemin comme un objet muni de méthodes, un seul import remplace toutos.path.- L'opérateur
/compose les chemins dans l'ordre de lecture, sans se soucier du séparateur système. Path.cwd()etPath.home()donnent des ancres portables pour construire les chemins..exists(),.is_file()et.is_dir()testent un chemin sans lever d'exception..mkdir(parents=True, exist_ok=True)crée une arborescence de façon rejouable..read_text()et.write_text()lisent et écrivent un fichier court en une ligne..iterdir(),.glob()et.rglob()parcourent un dossier, avec motif et récursion..name,.stem,.suffix,.parentet.partsdécomposent un chemin sans manipuler de chaîne.- pathlib est la façon moderne recommandée, préférable à
os.pathsur tout code neuf.
Pour aller plus loin
Section intitulée « Pour aller plus loin »pathlib gère les chemins ; ces guides couvrent le contenu des fichiers et l'automatisation qui va avec.
- Manipuler du JSON : sérialiser et charger des données structurées depuis un fichier.
- Créer une CLI avec Click : transformer un script qui manipule des fichiers en outil en ligne de commande.