Comment voir si un fichier existe ou non, sans utiliser l'instruction try
?
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
_
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.
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
import os.path
if os.path.isfile(filepath):
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"
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
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 :
Solutions possibles :
[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. RenvoieFalse
pour les liens symboliques brisés. Sur certaines plates-formes, cette fonction peut renvoyerFalse
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 ()
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
[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.
Fonctions de parcours du système de fichiers (et recherche dans les résultats avec les éléments correspondants)
[Python 3]: os. listdir ( path = '.' ) (ou [Python 3]: os. ) scandir ( path = '.' ) sur Python v 3.5 +, backport: [PyPI ]: scandir )
Sous le capot, les deux utilisent:
via [GitHub]: python/cpython - (maître) cpython/Modules/posixmodule.c
L'utilisation de scandir () au lieu de listdir () peut augmenter considérablement les performances du code qui a également besoin d'informations de type de fichier ou d'attribut de fichier, car os.DirEntry = Les objets exposent ces informations si le système d'exploitation les fournit lors de l'analyse d'un répertoire. Toutes les méthodes (os.DirEntry peuvent effectuer un appel système, mais is_dir () et is_file () n'exigent généralement qu'un appel système pour les liens symboliques; os.DirEntry.stat () nécessite toujours un appel système sur Unix mais n'en requiert qu'un pour les liens symboliques sous Windows.
os.listdir
(os.scandir
lorsqu'il est disponible)glob.glob
) os.listdir
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.
(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)
... 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 :
os.F_OK
dans l’appel, mais c’est juste pour la clarté (sa valeur est 0 )
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 .
__declspec(dllexport)
(pourquoi sur Terre, le régulier personne ferait cela?), le programme principal est chargeable mais quasiment inutilisableInstaller 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.
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 )):
[cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))" 0 [cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))" 512
Conclusion :
Note finale (s) :
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")
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
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:
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.
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
_
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
.
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
_
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()
etisfile()
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.
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.
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
.
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:
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
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():
...
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.
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.
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
):
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
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
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! :)
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']}
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 ).
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é.
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.
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.
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
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()
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):
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
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 ).
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
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)
Vous pouvez utiliser la méthode ouverte suivante pour vérifier si un fichier existe + est lisible:
open(inputFile, 'r')
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.
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)
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
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.
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."
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