Menu

Vérifier si un fichier existe en Python : os.path, pathlib et try/except

Trois façons de vérifier si un fichier existe en Python : os.path.exists et isfile, Path.exists et is_file de pathlib, et l'ouverture du fichier dans un try/except FileNotFoundError.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

La réponse courte

Pour vérifier si un fichier existe, utilise os.path.isfile() de la bibliothèque standard. Il renvoie True quand le chemin désigne un fichier ordinaire existant et False sinon. Il ne lève jamais d'erreur pour un chemin absent.

Les chemins sont relatifs au dossier dans lequel le programme s'exécute (le répertoire de travail courant), sauf si tu passes un chemin absolu comme /home/ada/notes.txt ou C:\Users\Ada\notes.txt.

La suite de cette page présente les autres façons de poser la question, ce qui les distingue, et le cas où il vaut mieux ne pas la poser du tout.

os.path.exists, isfile ou isdir

Le module os.path propose trois vérifications proches, qui répondent à des questions légèrement différentes :

FonctionRenvoie True quand le chemin est
os.path.exists(p)tout ce qui existe : un fichier, un dossier ou un lien symbolique valide
os.path.isfile(p)un fichier ordinaire existant
os.path.isdir(p)un dossier existant

La différence apparaît dès qu'un dossier entre en jeu :

Sortie :

reports True False True
reports/summary.txt True True False
reports/old.txt False False False

os.path.exists("reports") vaut True alors que reports est un dossier. Si ton code s'apprête à lire le chemin comme un fichier, exists n'est pas la bonne vérification : un dossier la passerait, et open("reports") échouerait ensuite (avec IsADirectoryError sous Linux et macOS, PermissionError sous Windows). Choisis isfile quand tu parles d'un fichier et isdir quand tu parles d'un dossier.

Deux détails de plus sur ces trois fonctions de os.path :

  • Un lien symbolique est suivi. Un lien qui pointe vers un vrai fichier compte comme un fichier ; un lien cassé (sa cible a disparu) renvoie False pour les trois.
  • Si Python n'a pas le droit de regarder dans un dossier, la vérification renvoie False au lieu de lever PermissionError. False signifie « introuvable ou inaccessible », pas strictement « n'existe pas ».

Vérifier avec pathlib

pathlib est l'API orientée objet de la bibliothèque standard pour les chemins, et la plupart du code récent l'utilise. Un objet Path offre les trois mêmes vérifications sous forme de méthodes :

Path.exists(), Path.is_file() et Path.is_dir() se comportent comme os.path.exists, isfile et isdir. L'opérateur / assemble les parties du chemin avec le séparateur propre au système d'exploitation, donc folder / "summary.txt" fonctionne aussi bien sous Windows que sous macOS et Linux. Consulte la gestion de fichiers pour lire et écrire à travers des objets Path.

Lequel choisir ? Si le reste de ton code manipule déjà des objets Path, reste sur pathlib. Si tu travailles avec de simples chaînes et les fonctions de os, os.path.isfile est tout aussi correct. Les deux donnent les mêmes réponses.

Pourquoi vérifier d'abord peut être une erreur

La raison la plus courante de vérifier qu'un fichier existe, c'est de l'ouvrir juste après :

import os

if os.path.isfile("config.txt"):
    with open("config.txt") as f:      # le fichier a peut-être déjà disparu
        settings = f.read()
else:
    settings = ""

Ce code a une faille. Entre l'appel à isfile() et l'appel à open(), un autre programme, un autre thread ou l'utilisateur peut supprimer ou renommer le fichier. La vérification a répondu True, l'ouverture échoue quand même, et ton programme plante avec FileNotFoundError malgré tout. Cette faille s'appelle une situation de compétition (race condition), ou « time of check to time of use ». Elle est rare sur ton propre ordinateur et beaucoup moins rare sur un serveur chargé où plusieurs processus partagent un dossier.

La solution consiste à supprimer la vérification séparée et à laisser open() servir de vérification. Python lève FileNotFoundError quand le fichier est absent, et tu gères ce cas dans le except :

Sortie :

theme=dark
(no settings file, using defaults)

Il n'y a plus qu'une opération au lieu de deux, donc plus rien avec quoi entrer en compétition. Ce style porte un nom dans la communauté Python : EAFP, « easier to ask forgiveness than permission » (il est plus facile de demander pardon que la permission). Le style inverse, vérifier d'abord, s'appelle LBYL, « look before you leap » (regarder avant de sauter). Python privilégie EAFP pour les fichiers parce que le système d'exploitation est le seul à connaître la réponse au moment où tu ouvres le fichier.

FileNotFoundError n'est pas le seul problème possible. Un chemin qui désigne un dossier lève IsADirectoryError (PermissionError sous Windows), et un fichier que tu n'as pas le droit de lire lève PermissionError. Ces trois exceptions sont des sous-classes de OSError, donc except OSError: attrape d'un coup tous les cas « impossible de l'ouvrir ». La page sur les exceptions explique comment choisir entre attraper une erreur précise et attraper toute une famille.

Quand une simple vérification suffit

Vérifier d'abord n'est pas une erreur dans tous les cas. C'est le bon outil quand tu as seulement besoin de la réponse et que tu ne t'apprêtes pas à agir sur le fichier à la ligne suivante :

  • choisir quel message afficher (« 3 parties sauvegardées trouvées »)
  • valider un chemin saisi par l'utilisateur avant de lancer une longue tâche
  • sauter un travail déjà fait, quand une réponse périmée ne coûte qu'une répétition

La règle pratique : si tu vas ouvrir, lire, écrire ou supprimer le fichier, fais-le dans un try. Si tu veux seulement savoir, isfile() ou Path.is_file() convient très bien.

Créer un fichier seulement s'il n'existe pas

La question inverse se pose aussi : « écris ce fichier, mais n'écrase jamais un fichier existant ». La version évidente a la même situation de compétition que plus haut :

if not os.path.exists("report.txt"):
    with open("report.txt", "w") as f:   # un autre processus peut le créer avant
        f.write("new report\n")

Le mode "x" (création exclusive) fait les deux étapes en une. Il crée le fichier, ou lève FileExistsError si le nom est déjà pris :

Sortie :

attempt 1: created report.txt
attempt 2: report.txt already exists, left it alone

Pour les dossiers, os.makedirs(path, exist_ok=True) et Path(path).mkdir(parents=True, exist_ok=True) créent le dossier et tous les parents manquants, et ne font rien s'il existe déjà. Inutile d'appeler isdir() avant.

Erreurs courantes

  • Utiliser exists() quand tu veux un fichier. Un dossier du même nom passe la vérification. Utilise isfile() ou Path.is_file().
  • Oublier d'où partent les chemins relatifs. "data.txt" est cherché dans le répertoire de travail courant, c'est-à-dire là où tu as lancé le programme, pas forcément le dossier qui contient le script. Pour trouver un fichier situé à côté du script, construis le chemin à partir de Path(__file__).parent.
  • Vérifier, puis ouvrir. Le fichier peut changer entre les deux. Ouvre-le dans un try et gère FileNotFoundError.
  • Attraper toutes les exceptions. except Exception: autour de open() cache aussi les fautes de frappe et les bugs du code qui lit le fichier. Attrape FileNotFoundError ou OSError.

Questions fréquentes

Comment vérifier si un fichier existe en Python ?

Importe os et appelle os.path.isfile("data.txt"), qui renvoie True uniquement pour un fichier ordinaire existant. Avec pathlib, c'est Path("data.txt").is_file(). Utilise os.path.exists() ou Path.exists() quand un dossier portant ce nom doit compter aussi.

Quelle est la différence entre os.path.exists et os.path.isfile ?

os.path.exists(p) vaut True pour tout ce qui se trouve à ce chemin : un fichier, un dossier ou un lien symbolique qui pointe vers quelque chose de réel. os.path.isfile(p) vaut True uniquement pour un fichier ordinaire, donc il renvoie False pour un dossier. os.path.isdir(p) est son équivalent pour les dossiers.

Faut-il vérifier qu'un fichier existe avant de l'ouvrir ?

En général, non. Le fichier peut être supprimé ou créé entre la vérification et l'appel à open(), donc la vérification ne garantit rien. Ouvre directement le fichier dans un try et gère FileNotFoundError dans le except. Une vérification à part est la bonne solution quand tu as seulement besoin de la réponse, par exemple pour choisir quel message afficher.

Comment créer un fichier seulement s'il n'existe pas ?

Ouvre-le avec le mode "x" : open("report.txt", "x"). Python crée le fichier, ou lève FileExistsError si quelque chose porte déjà ce nom. La vérification et la création se font en une seule étape, donc aucun autre programme ne peut s'intercaler entre les deux.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER