HOWTO · Python

Ouvrir un fichier situé dans un autre répertoire avec Python

Découvrez comment ouvrir avec Python un fichier situé hors du répertoire de travail, à l’aide d’un chemin absolu, de pathlib ou d’un chemin relatif.

Sur cette page

Transmettez le chemin du fichier à la fonction Python open(). Un chemin absolu désigne le fichier depuis la racine du système de fichiers ; un chemin relatif est résolu à partir du répertoire de travail actuel du processus (CWD). Celui-ci peut être différent du répertoire où se trouve votre script. Pour les fichiers d’un projet, pathlib.Path permet de construire facilement des chemins compatibles avec différents systèmes d’exploitation.

Comprendre les chemins et le répertoire de travail actuel

Le CWD est le répertoire que Python utilise pour résoudre les chemins relatifs. Il s’agit souvent du répertoire depuis lequel vous avez lancé le programme, et non de celui du script. Si un chemin ne mène pas à l’emplacement attendu, vérifiez le CWD :

import os

print(os.getcwd())

Un chemin absolu désigne un emplacement indépendamment du CWD. Un chemin relatif tel que data/notes.txt est interprété comme un chemin situé sous le CWD. Si open() ne trouve pas l’emplacement obtenu, Python déclenche FileNotFoundError. Avant de modifier votre code, vérifiez le chemin et le CWD.

Ouvrir un fichier avec un chemin absolu

Utilisez le chemin complet lorsque vous connaissez l’emplacement du fichier. Cet exemple crée un fichier à un emplacement temporaire absolu, le lit, puis affiche son contenu :

from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as directory:
    file_path = Path(directory) / "notes.txt"
    file_path.write_text("Meeting at 10", encoding="utf-8")
    with open(file_path, "r", encoding="utf-8") as file:
        print(file.read())

Le répertoire temporaire rend l’exemple indépendant des fichiers déjà présents sur votre machine. Dans votre programme, remplacez-le par l’emplacement réel du fichier. Le mode "r" ouvre le fichier en lecture de texte, et encoding="utf-8" explicite l’encodage du texte. L’instruction with ferme le fichier à la fin du bloc, même si une erreur survient pendant son exécution.

Sous Windows, vous pouvez écrire un chemin avec des barres obliques, avec une chaîne brute telle que r"C:\Users\Ada\notes.txt", ou en doublant les barres obliques inverses, comme dans "C:\\Users\\Ada\\notes.txt". Une barre oblique inverse ne commence une séquence d’échappement que si elle est suivie d’une séquence reconnue ; \n, par exemple, représente un saut de ligne. Un littéral de chaîne brute ne peut pas se terminer par une seule barre oblique inverse. Construire le chemin à partir de composants avec pathlib évite une bonne partie de ces précautions liées aux chaînes.

Construire des chemins avec pathlib

pathlib.Path est une classe qui représente et combine des chemins du système de fichiers. L’opérateur / assemble les composants selon les conventions de chemin du système d’exploitation utilisé. Cet exemple crée un fichier dans un répertoire voisin et l’ouvre à l’aide de son chemin absolu :

from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as parent:
    root = Path(parent)
    current = root / "app"
    other = root / "shared"
    current.mkdir()
    other.mkdir()
    target = other / "notes.txt"
    target.write_text("Shared notes", encoding="utf-8")

    file_path = target.resolve()
    with open(file_path, "r", encoding="utf-8") as file:
        print(file.read())

Dans un projet réel, partez d’un répertoire connu et ajoutez les noms des sous-répertoires, par exemple Path("/srv/project") / "data" / "notes.txt". Utilisez un répertoire de départ absolu si le programme doit fonctionner quel que soit le répertoire depuis lequel il a été lancé. Pour une cible existante, Path.resolve() renvoie un chemin absolu et peut faciliter le diagnostic des problèmes de chemin.

Utiliser un chemin relatif ou modifier le répertoire de travail

Imaginons que le projet contienne scripts/read_notes.py et shared/notes.txt, et que le CWD soit project/scripts. Depuis ce CWD, ../shared/notes.txt remonte à project, puis entre dans shared. Cette méthode est pratique si le répertoire de lancement est prévisible, mais le même chemin relatif peut désigner un autre emplacement si le programme démarre avec un CWD différent. Pour rattacher un chemin de projet au script, construisez-le plutôt à partir de Path(__file__).resolve().parent.

L’exemple exécutable suivant crée cette arborescence, définit le CWD du processus sur project/scripts, puis lit le fichier voisin avec une instruction with :

import os
from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as directory:
    project = Path(directory) / "project"
    scripts = project / "scripts"
    shared = project / "shared"
    scripts.mkdir(parents=True)
    shared.mkdir()
    (shared / "notes.txt").write_text("Project notes", encoding="utf-8")

    original_directory = os.getcwd()
    try:
        os.chdir(scripts)
        with open("../shared/notes.txt", "r", encoding="utf-8") as file:
            print(file.read())
    finally:
        os.chdir(original_directory)

Le chemin relatif est résolu à partir du CWD du processus, que cet exemple définit sur project/scripts ; il n’est pas résolu à partir du répertoire du fichier source.

Si un programme traite plusieurs fichiers situés dans un même répertoire, il peut modifier le CWD du processus, puis utiliser des chemins relatifs plus courts. Cet exemple crée le fichier d’entrée avant de changer de répertoire, puis restaure le CWD initial :

import os
from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as directory:
    target = Path(directory) / "notes.txt"
    target.write_text("Daily notes", encoding="utf-8")
    original_directory = os.getcwd()
    try:
        os.chdir(directory)
        with open("notes.txt", "r", encoding="utf-8") as file:
            print(file.read())
    finally:
        os.chdir(original_directory)

os.chdir() modifie l’état du processus entier : les chemins relatifs utilisés ailleurs dans le programme sont donc eux aussi résolus différemment. Restaurer le répertoire précédent limite cet effet. Pour un seul fichier, transmettre directement un chemin absolu ou un chemin pathlib est généralement plus simple. Si l’accès échoue malgré tout, vérifiez que le processus a le droit de lire le fichier, en plus d’en contrôler l’emplacement.