it-swarm-fr.com

Comment vérifier si un fichier existe sans exception?

Comment voir si un fichier existe ou non, sans utiliser l'instruction try ?

5178
spence91

Si vous vérifiez si vous pouvez faire quelque chose comme if file_exists: open_it(), il est préférable d'utiliser un try lors de la tentative d'ouverture. Vérifier et ensuite ouvrir risque de supprimer ou de déplacer le fichier ou quelque chose entre le moment de vérifier et le moment où vous essayez de l'ouvrir.

Si vous ne prévoyez pas d’ouvrir le fichier immédiatement, vous pouvez utiliser os.path.isfile

Retourne True si chemin est un fichier régulier existant. Cela suit les liens symboliques, donc islink () et isfile () peut être vrai pour le même chemin.

_import os.path
os.path.isfile(fname) 
_

si vous devez être sûr que c'est un fichier.

À partir de Python 3.4, le module pathlib offre une approche orientée objet (rétroporté à _pathlib2_ dans Python 2.7):

_from pathlib import Path

my_file = Path("/path/to/file")
if my_file.is_file():
    # file exists
_

Pour vérifier un répertoire, faites:

_if my_file.is_dir():
    # directory exists
_

Pour vérifier si un objet Path existe indépendamment du fait qu'il s'agisse d'un fichier ou d'un répertoire, utilisez exists():

_if my_file.exists():
    # path exists
_

Vous pouvez également utiliser resolve(strict=True) dans un bloc try:

_try:
    my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
    # doesn't exist
else:
    # exists
_
4764
rslite

Vous avez la fonction os.path.exists :

_import os.path
os.path.exists(file_path)
_

Ceci retourne True pour les fichiers et les répertoires mais vous pouvez utiliser plutôt

_os.path.isfile(file_path)
_

pour tester si c'est un fichier spécifiquement. Il s'ensuit des liens symboliques.

1971
PierreBdR

Contrairement à isfile() , exists() renverra True pour les répertoires.
Donc, selon que vous souhaitiez uniquement des fichiers ordinaires ou également des répertoires, vous utiliserez isfile() ou exists(). Voici une simple sortie REPL.

>>> print os.path.isfile("/etc/password.txt")
True
>>> print os.path.isfile("/etc")
False
>>> print os.path.isfile("/does/not/exist")
False
>>> print os.path.exists("/etc/password.txt")
True
>>> print os.path.exists("/etc")
True
>>> print os.path.exists("/does/not/exist")
False
911
bortzmeyer
import os.path

if os.path.isfile(filepath):
573
Paul

Utilisez os.path.isfile() avec os.access() :

import os
import os.path

PATH='./file.txt'

if os.path.isfile(PATH) and os.access(PATH, os.R_OK):
    print "File exists and is readable"
else:
    print "Either the file is missing or not readable"
276
Yugal Jindle
import os
os.path.exists(path) # Returns whether the path (directory or file) exists or not
os.path.isfile(path) # Returns whether the file exists or not
265
benefactual

Bien que presque tous les moyens possibles aient été répertoriés dans (au moins une des) réponses existantes (par exemple Python 3.4 des éléments spécifiques ont été ajoutés), je vais essayer de tout regrouper.

Note : chaque élément de Python le code de bibliothèque standard que je vais publier, appartient à la version 3.5.3 .

Enoncé du problème :

  1. Vérifier le fichier ( arguable : aussi le dossier (fichier "spécial")?)
  2. Ne pas utiliser try / sauf / else / finally bloque

Solutions possibles :

  1. [Python 3]: os.path. existe ( chemin ) (vérifiez également les autres membres de la famille de fonctions comme os.path.isfile, os.path.isdir, os.path.lexists pour des comportements légèrement différents.)

    os.path.exists(path)
    

    Retourne True if chemin fait référence à un chemin existant ou à un descripteur de fichier ouvert. Renvoie False pour les liens symboliques brisés. Sur certaines plates-formes, cette fonction peut renvoyer False si l'autorisation n'est pas accordée pour exécuter os.stat () sur le fichier demandé, même si chemin existe physiquement.

    Tout va bien, mais si vous suivez l'arbre d'importation:

    • os.path - posixpath.py ( ntpath.py )

      • genericpath.py , ligne ~ # 20 +

        def exists(path):
            """Test whether a path exists.  Returns False for broken symbolic links"""
            try:
                st = os.stat(path)
            except os.error:
                return False
            return True
        

    c'est juste un try / sauf bloquer autour de [Python 3]: os. stat ( chemin, *, dir_fd = None, follow_symlinks = True ) . Donc, votre code est try / sauf libre, mais plus bas dans l'enchaînement d'images (au moins) un tel bloquer. Cela s'applique également aux autres fonctions (, notamment os.path.isfile).

    1.1. [Python 3]: Path. is_file ()

    • C'est un moyen plus sophistiqué (et plus python ic) de gérer les chemins, mais
    • Sous le capot, il fait exactement la même chose ( pathlib.py , line ~ # 1330 ):

      def is_file(self):
          """
          Whether this path is a regular file (also True for symlinks pointing
          to regular files).
          """
          try:
              return S_ISREG(self.stat().st_mode)
          except OSError as e:
              if e.errno not in (ENOENT, ENOTDIR):
                  raise
              # Path doesn't exist or is a broken symlink
              # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
              return False
      
  2. [Python 3]: Avec les gestionnaires de contexte d'instruction . Soit:

    • Créer une:

      class Swallow:  # Dummy example
          swallowed_exceptions = (FileNotFoundError,)
      
          def __enter__(self):
              print("Entering...")
      
          def __exit__(self, exc_type, exc_value, exc_traceback):
              print("Exiting:", exc_type, exc_value, exc_traceback)
              return exc_type in Swallow.swallowed_exceptions  # only swallow FileNotFoundError (not e.g. TypeError - if the user passes a wrong argument like None or float or ...)
      
      • Et son utilisation - je vais reproduire le comportement os.path.isfile (notez qu'il ne s'agit que d'une démonstration, ne ( ne tentez pas d'écrire ce code) pour production ):

        import os
        import stat
        
        
        def isfile_seaman(path):  # Dummy func
            result = False
            with Swallow():
                result = stat.S_ISREG(os.stat(path).st_mode)
            return result
        
    • Utilisez [Python 3]: contextlib. supprime ( * exceptions ) - qui était spécifiquement conçu pour supprimer sélectivement les exceptions


    Mais, ils semblent être des wrappers over try / sauf / else / finally bloque, comme (Python 3 ]: Le avec déclaration déclare:

    Cela permet d’encapsuler les modèles d’utilisation courants try ... sauf ... enfin pour une réutilisation aisée.

  3. Fonctions de parcours du système de fichiers (et recherche dans les résultats avec les éléments correspondants)


    Comme ils parcourent les dossiers, (dans la plupart des cas), ils sont inefficaces pour notre problème (il existe des exceptions, comme non génériques glob bing - as @ShadowRanger souligné), donc je ne vais pas insister sur eux. Sans oublier que dans certains cas, le traitement du nom de fichier peut être requis.

  4. (Python 3): os. accès ( chemin, mode, *, dir_fd = None, effective_ids = False) , follow_symlinks = True ) dont le comportement est proche de os.path.exists (en fait, il est plus large, principalement à cause de la 2dakota du Nord argument)

    • Les autorisations utilisateur peuvent restreindre la "visibilité" du fichier car le document indique:

      ... teste si l'utilisateur appelant a l'accès spécifié à path . mode devrait être F_OK pour tester l'existence d'un chemin ...

    os.access("/tmp", os.F_OK)

    Depuis que je travaille aussi dans C, j'utilise aussi cette méthode car sous le capot, il appelle natif API s (encore une fois, via "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c" ), mais il ouvre également une porte pour les éventuelles erreurs de l'utilisateur , et ce n'est pas comme Python ic comme les autres variantes. Donc, comme l'a souligné à juste titre @AaronHall, ne l'utilisez pas si vous ne savez pas ce que vous faites:

    Remarque : appeler natif API s est également possible via [Python 3] : ctypes - Une bibliothèque de fonctions étrangères pour Python , mais dans la plupart des cas, c'est plus compliqué.

    ( Win spécifique): Depuis vcruntime * ( msvcr * ) . dll exporte un [MS.Docs]: _access, _waccess famille de fonctions voici un exemple:

    Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe", os.F_OK)
    0
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe.notexist", os.F_OK)
    -1
    

    Notes :

    • Bien que ce ne soit pas une bonne pratique, j’utilise os.F_OK dans l’appel, mais c’est juste pour la clarté (sa valeur est 0 )
    • J'utilise _ waccess pour que le même code fonctionne sur Python3 et Python2 (malgré unicode différences liées entre eux)
    • Bien que cela cible un domaine très spécifique, , il n'a été mentionné dans aucune des réponses précédentes


    Le Lnx ( Ubtu (16 x64) ) également:

    Python 3.5.2 (default, Nov 17 2016, 17:05:23)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK)
    0
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp.notexist", os.F_OK)
    -1
    

    Notes :

    • Au lieu de cela, coder en dur libc le chemin ( "/ lib/x86_64-linux-gnu/libc.so.6" ) qui peut (et très probablement, variera) d’un système à l’autre, None (ou la chaîne vide) peut être passé à CDLL constructeur (ctypes.CDLL(None).access(b"/tmp", os.F_OK)). Selon [man7]: DLOPEN (3) :

      Si nom_fichier est NULL, le descripteur renvoyé est destiné au programme principal. Lorsque donné à dlsym (), ce descripteur provoque la recherche d'un symbole dans le programme principal, suivi de tous les objets partagés chargés au démarrage du programme, puis tous les objets partagés chargés par dlopen () avec l'indicateur RTLD_GLOBAL .

      • Le programme principal (actuel) ( python ) est lié à libc , donc ses symboles (y compris access ) sera chargé
      • Ceci doit être manipulé avec précaution, car des fonctions comme main , Py_Main et (tous les) autres sont disponibles; les appeler pourrait avoir des effets désastreux (sur le programme actuel)
      • Cela ne s'applique pas également à Win (mais ce n'est pas si grave, car msvcrt.dll se trouve dans "% SystemRoot%\System32" qui est dans % PATH% par défaut). Je voulais aller plus loin et reproduire ce comportement sur Win (et soumettre un correctif), mais il se trouve que [MS.Docs]: fonction GetProcAddress seulement "voit" symboles exportés, donc à moins que quelqu'un ne déclare les fonctions dans l'exécutable principal sous la forme __declspec(dllexport) (pourquoi sur Terre, le régulier personne ferait cela?), le programme principal est chargeable mais quasiment inutilisable
  5. Installer un module tiers avec des capacités de système de fichiers

    Très probablement, utilisera l'une des méthodes ci-dessus (peut-être avec de légères personnalisations).
    Un exemple serait (encore, Win spécifique) [GitHub]: mhammond/pywin32 - Python pour Windows (pywin32 ) Extensions , qui est un Python WINAPI s.

    Mais, puisque cela ressemble plus à une solution de contournement, je m'arrête ici.

  6. Une autre solution de contournement (boiteuse) ( gainarie ) est (comme j'aime l'appeler), le sysadmin approche: use Python en tant que wrapper pour exécuter des commandes Shell

    • Win :

      (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe\" > nul 2>&1'))"
      0
      
      (py35x64_test) e:\Work\Dev\StackOverflow\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe.notexist\" > nul 2>&1'))"
      1
      
    • Nix ( Lnx ( Ubtu )):

      [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))"
      0
      [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))"
      512
      

Conclusion :

  • Faites utilisez try / sauf / autre / finally bloque, car ils peuvent vous éviter une série de problèmes désagréables. La performance est un contre-exemple auquel je peux penser: de tels blocs sont coûteux, alors essayez de ne pas les placer dans un code censé être exécuté des centaines de milliers de fois par seconde (mais dans la plupart des cas, cela implique un accès au disque, ce ne sera pas le cas).

Note finale (s) :

  • Je vais essayer de le garder à jour, toutes les suggestions sont les bienvenues, je vais incorporer tout ce qui est utile qui viendra dans la réponse
222
CristiFati

C'est le moyen le plus simple de vérifier si un fichier existe. Juste parce que le fichier existait lorsque vous avez coché pas garantie qu'il sera là lorsque vous devrez l'ouvrir.

import os
fname = "foo.txt"
if os.path.isfile(fname):
    print("file does exist at this time")
else:
    print("no such file exists at this time")
149
un33k

Python 3.4 + a un module de chemin orienté objet: pathlib . En utilisant ce nouveau module, vous pouvez vérifier si un fichier existe comme ceci:

import pathlib
p = pathlib.Path('path/to/file')
if p.is_file():  # or p.is_dir() to see if it is a directory
    # do stuff

Vous pouvez (et devriez normalement) continuer à utiliser un bloc try/except lors de l'ouverture de fichiers:

try:
    with p.open() as f:
        # do awesome stuff
except OSError:
    print('Well darn.')

Le module pathlib contient de nombreux éléments intéressants: un agrandissement pratique, la vérification du propriétaire du fichier, la jonction plus facile du chemin, etc. Si vous utilisez une version antérieure de Python (version 2.6 ou ultérieure), vous pouvez toujours installer pathlib avec pip:

# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2

Puis importez-le comme suit:

# Older Python versions
import pathlib2 as pathlib
136
Cody Piersall

Préférez l'instruction try. C'est considéré comme un meilleur style et évite les conditions de course.

Ne prenez pas ma parole pour cela. Il y a beaucoup de soutien pour cette théorie. Voici un couple:

120
pkoch

Comment vérifier si un fichier existe, en utilisant Python, sans utiliser une instruction try?

Maintenant disponible depuis Python 3.4, importez et instanciez un objet Path avec le nom du fichier, puis cochez la méthode _is_file_ (notez que cela renvoie True pour les liens symboliques pointant également vers les fichiers normaux):

_>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False
_

Si vous êtes sur Python 2, vous pouvez effectuer un backport vers le module pathlib de pypi, pathlib2 , ou bien vérifier isfile à partir du module _os.path_:

_>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False
_

Maintenant, ce qui précède est probablement la meilleure réponse directe pragmatique ici, mais il existe une possibilité de condition de concurrence (selon ce que vous essayez d'accomplir) et le fait que l'implémentation sous-jacente utilise un try, mais Python utilise try partout dans son implémentation.

Comme Python utilise try partout, il n’ya vraiment aucune raison d’éviter une implémentation qui l’utilise.

Mais le reste de cette réponse tente de prendre en compte ces mises en garde.

Réponse plus longue, beaucoup plus pédante

Disponible depuis Python3.4, utilisez le nouvel objet Path dans pathlib. Notez que _.exists_ n’est pas tout à fait correct, car les répertoires ne sont pas des fichiers (sauf au sens unix où tout est un fichier).

_>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True
_

Nous devons donc utiliser _is_file_:

_>>> root.is_file()
False
_

Voici l'aide sur _is_file_:

_is_file(self)
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).
_

Alors prenons un fichier que nous savons être un fichier:

_>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True
_

Par défaut, NamedTemporaryFile supprime le fichier lorsqu'il est fermé (et se fermera automatiquement lorsqu'il n'y aura plus de références).

_>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False
_

Si vous creusez dans l'implémentation , cependant, vous verrez que _is_file_ utilise try:

_def is_file(self):
    """
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).
    """
    try:
        return S_ISREG(self.stat().st_mode)
    except OSError as e:
        if e.errno not in (ENOENT, ENOTDIR):
            raise
        # Path doesn't exist or is a broken symlink
        # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
        return False
_

Conditions de course: Pourquoi nous aimons essayer

Nous aimons try car cela évite les conditions de concurrence. Avec try, vous essayez simplement de lire votre fichier, en s’attendant à ce qu’il soit là, et si ce n’est pas le cas, vous interceptez l’exception et appliquez le comportement de secours qui vous convient.

Si vous voulez vérifier qu'un fichier existe avant de tenter de le lire, que vous voulez peut-être le supprimer, vous utilisez peut-être plusieurs threads ou processus, ou qu'un autre programme est au courant de ce fichier et peut le supprimer - vous courez le risque de une condition de concurrence si vous vérifiez qu'elle existe, car vous êtes en course pour l'ouvrir avant son la condition (son existence) change.

Les conditions de course sont très difficiles à déboguer car il existe une très petite fenêtre dans laquelle elles peuvent entraîner l'échec de votre programme.

Mais si telle est votre motivation, vous pouvez obtenir la valeur d'une instruction try à l'aide du gestionnaire de contexte suppress.

Eviter les conditions de course sans déclaration d'essai: suppress

Python 3.4 nous donne le gestionnaire de contexte suppress (anciennement le gestionnaire de contexte ignore ), qui effectue la même chose de manière sémantique en moins de lignes, tout en respectant (du moins superficiellement) le demande originale d'éviter une déclaration try:

_from contextlib import suppress
from pathlib import Path
_

Usage:

_>>> with suppress(OSError), Path('doesnotexist').open() as f:
...     for line in f:
...         print(line)
... 
>>>
>>> with suppress(OSError):
...     Path('doesnotexist').unlink()
... 
>>> 
_

Pour les Pythons antérieurs, vous pourriez lancer votre propre suppress, mais sans un try sera plus détaillé que avec. Je crois que c'est en fait la seule réponse qui n'utilise pas try à aucun niveau du Python qui peut être appliqué avant Python 3.4 car il utilise plutôt un gestionnaire de contexte:

_class suppress(object):
    def __init__(self, *exceptions):
        self.exceptions = exceptions
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is not None:
            return issubclass(exc_type, self.exceptions)
_

Peut-être plus facile avec un essai:

_from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass
_

Autres options qui ne répondent pas à la demande "sans essai":

isfile

_import os
os.path.isfile(path)
_

à partir du docs :

os.path.isfile(path)

Renvoie True si path est un fichier régulier existant. Cela suit les liens symboliques, donc islink() et isfile() peuvent être vrais pour le même chemin.

Mais si vous examinez le source de cette fonction, vous verrez qu'il utilise en fait une instruction try:

_# This follows symbolic links, so both islink() and isdir() can be true
# for the same path on systems that support symlinks
def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = os.stat(path)
    except os.error:
        return False
    return stat.S_ISREG(st.st_mode)
_
_>>> OSError is os.error
True
_

Tout ce que cela fait est d'utiliser le chemin indiqué pour voir s'il peut obtenir des statistiques, d'attraper OSError, puis de vérifier s'il s'agit d'un fichier s'il n'a pas généré d'exception.

Si vous avez l'intention de faire quelque chose avec le fichier, je suggérerais de le tenter directement avec un essai, sauf pour éviter une situation de concurrence critique:

_try:
    with open(path) as f:
        f.read()
except OSError:
    pass
_

os.access

_os.access_ est disponible pour Unix et Windows, mais pour l'utiliser, vous devez passer des indicateurs, ce qui ne différencie pas les fichiers des répertoires. Ceci est plus utilisé pour tester si l'utilisateur invoquant réel a accès dans un environnement à privilèges élevés:

_import os
os.access(path, os.F_OK)
_

Il souffre également des mêmes problèmes de condition de course que isfile. De la docs :

Remarque: Utilisation de access () pour vérifier si un utilisateur est autorisé, par exemple, à ouvrir un fichier avant de le faire en utilisant open () crée un trou de sécurité, car l'utilisateur peut exploiter le court intervalle de temps entre la vérification et l'ouverture du fichier pour le manipuler. Il est préférable d’utiliser les techniques EAFP. Par exemple:

_if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()
return "some default data"
_

est mieux écrit comme:

_try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()
_

Évitez d’utiliser _os.access_. Il s’agit d’une fonction de bas niveau offrant plus d’occasions d’erreur utilisateur que les objets et fonctions de niveau supérieur décrits ci-dessus.

Critique d'une autre réponse:

Une autre réponse dit ceci à propos de _os.access_:

Personnellement, je préfère celui-ci car il appelle, à l’envers, des API natives (via "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), mais il ouvre également une porte pour éviter les erreurs éventuelles des utilisateurs, et il n’est pas aussi pythonique que d’autres variantes. :

Cette réponse indique qu'elle préfère une méthode non pythonique, sujette aux erreurs, sans justification. Cela semble encourager les utilisateurs à utiliser des API de bas niveau sans les comprendre.

Il crée également un gestionnaire de contexte qui, en renvoyant inconditionnellement True, permet à toutes les exceptions (y compris KeyboardInterrupt et SystemExit!) De passer en silence, ce qui est un bon moyen de masquer les bogues.

Cela semble encourager les utilisateurs à adopter de mauvaises pratiques.

112
Aaron Hall
import os
#Your path here e.g. "C:\Program Files\text.txt"
#For access purposes: "C:\\Program Files\\text.txt"
if os.path.exists("C:\..."):   
    print "File found!"
else:
    print "File not found!"

L'importation os facilite la navigation et l'exécution d'actions standard avec votre système d'exploitation.

Pour référence, voir aussi Comment vérifier si un fichier existe en utilisant Python?

Si vous avez besoin d'opérations de haut niveau, utilisez shutil.

84
喬治扎菲

Test de fichiers et de dossiers avec os.path.isfile(), os.path.isdir() et os.path.exists()

En supposant que le "chemin" soit un chemin valide, ce tableau indique les résultats renvoyés par chaque fonction pour les fichiers et les dossiers:

enter image description here

Vous pouvez également tester si un fichier est un certain type de fichier en utilisant os.path.splitext() pour obtenir l'extension (si vous ne le connaissez pas déjà).

>>> import os
>>> path = "path to a Word document"
>>> os.path.isfile(path)
True
>>> os.path.splitext(path)[1] == ".docx" # test if the extension is .docx
True
79
Tom Fuller

En 2016, le meilleur moyen consiste toujours à utiliser os.path.isfile:

>>> os.path.isfile('/path/to/some/file.txt')

Ou dans Python 3, vous pouvez utiliser pathlib:

import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
    ...
68
KaiBuxe

Il ne semble pas y avoir de différence fonctionnelle significative entre try/except et isfile(), vous devez donc utiliser celle qui a du sens.

Si vous voulez lire un fichier, s’il existe, faites

try:
    f = open(filepath)
except IOError:
    print 'Oh dear.'

Mais si vous voulez juste renommer un fichier s’il existe et que vous n’avez donc pas besoin de l’ouvrir, ne le faites pas.

if os.path.isfile(filepath):
    os.rename(filepath, filepath + '.old')

Si vous voulez écrire dans un fichier, s'il n'existe pas encore, faites

# python 2
if not os.path.isfile(filepath):
    f = open(filepath, 'w')

# python 3, x opens for exclusive creation, failing if the file already exists
try:
    f = open(filepath, 'wx')
except IOError:
    print 'file already exists'

Si vous avez besoin d'un verrouillage de fichier, c'est une autre affaire.

63
chad

Vous pouvez essayer ceci (plus sûr):

try:
    # http://effbot.org/zone/python-with-statement.htm
    # 'with' is safer to open a file
    with open('whatever.txt') as fh:
        # Do something with 'fh'
except IOError as e:
    print("({})".format(e))

La sortie serait:

([Errno 2] Aucun fichier ou répertoire de ce type: 'quel que soit le type de fichier')

Ensuite, en fonction du résultat, votre programme peut simplement continuer à partir de là ou vous pouvez coder pour l’arrêter si vous le souhaitez.

56
philberndt

Bien que je recommande toujours d'utiliser les instructions try et except, voici quelques possibilités pour vous (mon préféré consiste à utiliser os.access):

  1. Essayez d'ouvrir le fichier:

    L'ouverture du fichier vérifiera toujours l'existence du fichier. Vous pouvez créer une fonction comme ceci:

    def File_Existence(filepath):
        f = open(filepath)
        return True
    

    Si la valeur est False, l'exécution s'arrête avec une erreur IOError ou OSError non gérée dans les versions ultérieures de Python. Pour attraper l'exception, vous devez utiliser une clause try except. Bien sûr, vous pouvez toujours utiliser une instruction try except` comme ceci (grâce à hsandt pour m'avoir fait réfléchir):

    def File_Existence(filepath):
        try:
            f = open(filepath)
        except IOError, OSError: # Note OSError is for later versions of Python
            return False
    
        return True
    
  2. Utilisez os.path.exists(path):

    Cela vérifiera l'existence de ce que vous spécifiez. Cependant, il vérifie les fichiers et les répertoires , alors méfiez-vous de la façon dont vous les utilisez.

    import os.path
    >>> os.path.exists("this/is/a/directory")
    True
    >>> os.path.exists("this/is/a/file.txt")
    True
    >>> os.path.exists("not/a/directory")
    False
    
  3. Utilisez os.access(path, mode):

    Cela vérifiera si vous avez accès au fichier. Il va vérifier les autorisations. Sur la base de la documentation os.py, en saisissant os.F_OK, il vérifiera l’existence du chemin. Cependant, cela créera une faille de sécurité, car quelqu'un peut attaquer votre fichier en utilisant le temps qui s'écoule entre la vérification des autorisations et l'ouverture du fichier. Vous devriez plutôt aller directement à l'ouverture du fichier au lieu de vérifier ses autorisations. ( EAFP vs LBYP ). Si vous n'allez pas ouvrir le fichier par la suite et que vous ne vérifiez que son existence, vous pouvez l'utiliser.

    Quoi qu'il en soit, ici:

    >>> import os
    >>> os.access("/is/a/file.txt", os.F_OK)
    True
    

Je devrais également mentionner qu'il y a deux manières pour que vous ne puissiez pas vérifier l'existence d'un fichier. Le problème sera permission denied ou no such file or directory. Si vous attrapez un IOError, définissez le IOError as e (comme ma première option), puis tapez print(e.args) afin de pouvoir déterminer votre problème, espérons-le. J'espère que ça aide! :)

50
Zizouz212

Date: 2017-12-04

Toutes les solutions possibles ont été énumérées dans d’autres réponses.

Voici un moyen intuitif et discutable de vérifier l’existence d’un fichier:

import os
os.path.isfile('~/file.md')  # Returns True if exists, else False
# additionaly check a dir
os.path.isdir('~/folder')  # Returns True if the folder exists, else False
# check either a dir or a file
os.path.exists('~/file')

J'ai fait une feuille de triche exhaustive pour votre référence:

#os.path methods in exhaustive cheatsheet
{'definition': ['dirname',
               'basename',
               'abspath',
               'relpath',
               'commonpath',
               'normpath',
               'realpath'],
'operation': ['split', 'splitdrive', 'splitext',
               'join', 'normcase'],
'compare': ['samefile', 'sameopenfile', 'samestat'],
'condition': ['isdir',
              'isfile',
              'exists',
              'lexists'
              'islink',
              'isabs',
              'ismount',],
 'expand': ['expanduser',
            'expandvars'],
 'stat': ['getatime', 'getctime', 'getmtime',
          'getsize']}
44
Algebra

De plus, os.access():

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()

Étant R_OK, W_OK et X_OK les indicateurs permettant de tester les autorisations ( doc ).

35
zgoda

Si le fichier est destiné à l'ouverture, vous pouvez utiliser l'une des techniques suivantes:

>>> with open('somefile', 'xt') as f: #Using the x-flag, Python3.3 and above
...     f.write('Hello\n')

>>> if not os.path.exists('somefile'): 
...     with open('somefile', 'wt') as f:
...         f.write("Hello\n")
... else:
...     print('File already exists!')

UPDATE

Juste pour éviter toute confusion et sur la base des réponses que j'ai obtenues, la réponse actuelle trouve soit un fichier o un répertoire portant le nom donné.

32
bergercookie
if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

L'augmentation des exceptions est considérée comme une approche acceptable et Pythonic du contrôle de flux dans votre programme. Pensez à gérer les fichiers manquants avec IOErrors. Dans ce cas, une exception IOError sera générée si le fichier existe mais que l'utilisateur ne dispose pas d'autorisations de lecture.

SRC: http://www.pfinn.net/python-check-if-file-exists.html

21
Pedro Lobito

Si vous avez déjà importé NumPy à d'autres fins, il n'est pas nécessaire d'importer d'autres bibliothèques telles que pathlib, os, paths, etc.

import numpy as np
np.DataSource().exists("path/to/your/file")

Cela retournera vrai ou faux en fonction de son existence.

18
durjoy

Vous pouvez écrire la suggestion de Brian sans le try:.

from contextlib import suppress

with suppress(IOError), open('filename'):
    process()

suppress fait partie de Python 3.4. Dans les anciennes versions, vous pouvez rapidement écrire votre propre suppression:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass
17
Chris

Vérifier que le fichier ou le répertoire existe

Vous pouvez suivre ces trois manières:

Note1: Le os.path.isfile utilisé uniquement pour les fichiers

import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists

Note2: Le os.path.exists utilisé pour les fichiers et les répertoires

import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists

La méthode pathlib.Path (incluse dans Python 3+, installable avec pip pour Python 2)

from pathlib import Path
Path(filename).exists()
16
Ali Hallaji

Ajouter une autre légère variation qui ne se reflète pas exactement dans les autres réponses.

Ceci gérera le cas où file_path sera None ou une chaîne vide.

def file_exists(file_path):
    if not file_path:
        return False
    Elif not os.path.isfile(file_path):
        return False
    else:
        return True

Ajouter une variante basée sur une suggestion de Shahbaz

def file_exists(file_path):
    if not file_path:
        return False
    else:
        return os.path.isfile(file_path)

Ajouter une variante basée sur une suggestion de Peter Wood

def file_exists(file_path):
    return file_path and os.path.isfile(file_path):
15
Marcel Wilson

Je suis l'auteur d'un package qui existe depuis environ 10 ans et dont la fonction répond directement à cette question. Fondamentalement, si vous utilisez un système autre que Windows, il utilise Popen pour accéder à find. Cependant, si vous êtes sous Windows, il réplique find avec un lecteur de système de fichiers efficace.

Le code lui-même n'utilise pas de bloc try… sauf pour déterminer le système d'exploitation et ainsi vous diriger vers le style "Unix" find ou la main-Buillt find. Les tests de synchronisation ont montré que la try permettait de déterminer plus rapidement le système d'exploitation. J'en ai donc utilisé une ici (mais nulle part ailleurs).

>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']

Et le doc…

>>> print pox.find.__doc__
find(patterns[,root,recurse,type]); Get path to a file or directory

    patterns: name or partial name string of items to search for
    root: path string of top-level directory to search
    recurse: if True, recurse down from root directory
    type: item filter; one of {None, file, dir, link, socket, block, char}
    verbose: if True, be a little verbose about the search

    On some OS, recursion can be specified by recursion depth (an integer).
    patterns can be specified with basic pattern matching. Additionally,
    multiple patterns can be specified by splitting patterns with a ';'
    For example:
        >>> find('pox*', root='..')
        ['/Users/foo/pox/pox', '/Users/foo/pox/scripts/pox_launcher.py']

        >>> find('*shutils*;*init*')
        ['/Users/foo/pox/pox/shutils.py', '/Users/foo/pox/pox/__init__.py']

>>>

La mise en œuvre, si vous voulez bien regarder, est ici: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L19

15
Mike McKerns

Voici une commande Python d'une ligne pour l'environnement de ligne de commande Linux. Je trouve cela TRÈS HANDY puisque je ne suis pas un type Bash aussi sexy.

python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"

J'espère que ceci est utile.

Comment puis-je vérifier si un fichier existe sans utiliser l'instruction try?

En 2016, c'est toujours le moyen le plus simple de vérifier si un fichier existe et s'il s'agit d'un fichier:

import os
os.path.isfile('./file.txt')    # Returns True if exists, else False

isfile n'est en réalité qu'une méthode d'assistance qui utilise en interne os.stat et stat.S_ISREG(mode) en dessous. Ce os.stat est une méthode de niveau inférieur qui vous fournira des informations détaillées sur les fichiers, les répertoires, les sockets, les tampons, etc. Plus sur os.stat ici

Remarque: Toutefois, cette approche ne verrouille en aucune manière le fichier. Par conséquent, votre code peut devenir vulnérable à " heure de vérification à l'heure d'utilisation "(TOCTTOU) bugs.

Donc, lever des exceptions est considéré comme une approche acceptable, et Pythonic, pour le contrôle de flux dans votre programme. Et on devrait envisager de traiter les fichiers manquants avec IOErrors, plutôt que les déclarations if (, simplement un conseil ).

11
Inconnu

Vous pouvez utiliser la bibliothèque "OS" de Python:

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
11
Pradip Das
import os.path

def isReadableFile(file_path, file_name):
    full_path = file_path + "/" + file_name
    try:
        if not os.path.exists(file_path):
            print "File path is invalid."
            return False
        Elif not os.path.isfile(full_path):
            print "File does not exist."
            return False
        Elif not os.access(full_path, os.R_OK):
            print "File cannot be read."
            return False
        else:
            print "File can be read."
            return True
    except IOError as ex:
        print "I/O error({0}): {1}".format(ex.errno, ex.strerror)
    except Error as ex:
        print "Error({0}): {1}".format(ex.errno, ex.strerror)
    return False
#------------------------------------------------------

path = "/usr/khaled/documents/puzzles"
fileName = "puzzle_1.txt"

isReadableFile(path, fileName)
9
Khaled.K

Vous pouvez utiliser la méthode ouverte suivante pour vérifier si un fichier existe + est lisible:

open(inputFile, 'r')
9
user3197473
import os
path = /path/to/dir

root,dirs,files = os.walk(path).next()
if myfile in files:
   print "yes it exists"

Ceci est utile lors de la recherche de plusieurs fichiers. Ou vous voulez faire une intersection/soustraction avec une liste existante.

8
Jesvin Jose

Pour vérifier si un fichier existe,

from sys import argv

from os.path import exists
script, filename = argv
target = open(filename)
print "file exists: %r" % exists(filename)
6
Hanson

Vous pouvez utiliser os.listdir pour vérifier si un fichier se trouve dans un certain répertoire.

import os
if 'file.ext' in os.listdir('dirpath'):
    #code
4
iPhynx
import os

# for testing purpose args defaulted to current folder & file. 
# returns True if file found
def file_exists(FOLDER_PATH='../', FILE_NAME=__file__):
    return os.path.isdir(FOLDER_PATH) \
        and os.path.isfile(os.path.join(FOLDER_PATH, FILE_NAME))

En gros, une vérification de dossier, puis une vérification de fichier avec le séparateur de répertoire approprié à l'aide de os.path.join.

3
Vimal Maheedharan

Vous devriez certainement utiliser celui-ci.

from os.path import exists

if exists("file") == True:
    print "File exists."
Elif exists("file") == False:
    print "File doesn't exist."
2
user2154354

Ce n'est probablement pas nécessaire, mais si c'est le cas, voici du code

import os

def file_exists(path, filename):
    for file_or_folder in os.listdir(path):
        if file_or_folder == filename:
            return True
    return False