Comment puis-je vérifier si un fichier existe en python?
Comment puis-je voir si un fichier existe ou non, sans utiliser la déclaration try
?
30 réponses
si la raison que vous vérifiez est que vous pouvez faire quelque chose comme if file_exists: open_it()
, il est plus sûr d'utiliser un try
autour de la tentative de l'ouvrir. Vérifier puis ouvrir risque que le fichier soit supprimé ou déplacé ou quelque chose entre quand vous vérifiez et quand vous essayez de l'ouvrir.
Si vous n'avez pas l'intention d'ouvrir le fichier immédiatement, vous pouvez utiliser os.path.isfile
Retour
True
si le chemin d'accès est un fichier régulier. Ceci suit des liens symboliques, de sorte que les deux islink() et isfile() peuvent être vrais pour le même chemin.
import os.path
os.path.isfile(fname)
si vous avez besoin d'être sûr que c'est un fichier.
à partir de Python 3.4, le pathlib
module offre une approche orientée objet (rétroporté à pathlib2
en 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, faire:
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()
dans un try
bloc:
try:
my_abs_path = my_file.resolve()
except FileNotFoundError:
# doesn't exist
else:
# exists
vous avez la os.path.exists
fonction:
import os.path
os.path.exists(file_path)
cela renvoie True
pour les fichiers et les répertoires mais vous pouvez utiliser
os.path.isfile(file_name)
pour vérifier si c'est un fichier spécifique. Il suit les liens symboliques.
contrairement à isfile()
, exists()
retournera True
pour les répertoires.
Ainsi, selon que vous voulez seulement des fichiers simples ou aussi des répertoires, vous utiliserez isfile()
ou exists()
. Voici une sortie REPL simple.
>>> 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
utiliser 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
2017 / 12 / 22 :
bien que presque tous les moyens possibles aient été listés dans (au moins un des) réponses existantes (par exemple Python 3.4 des trucs spécifiques ont été ajoutés), je vais essayer de tout regrouper.
Note : chaque morceau de Python code de bibliothèque standard que je vais poster, appartient à la version 3.5.3 (les citations de doc sont la version 3 spécifique).
énoncé du Problème :
- Vérifier les fichiers ( soutenables : dossier ("spécial" fichier) ?) l'existence d'une
- N'utilisez pas
try
/except
/else
/finally
blocs
solutions possibles :
-
[os.chemin. existe ( chemin ) (vérifier également d'autres membres de la famille fonction comme
os.path.isfile
,os.path.isdir
,os.path.lexists
pour des comportements légèrement différents)os.path.exists(path)
Retour
True
si chemin fait référence à un chemin existant ou un descripteur de fichier ouvert. RetournerFalse
Pour liens symboliques rompus. Sur certaines plateformes, cette fonction peut retournerFalse
si la permission n'est pas accordée pour exécuter os.stat () sur le fichier demandé, même si le chemin existe physiquement.tout bon, 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/except
bloc autour de [Python]: os. stat ( path, *, dir_fd=None, follow_symlinks=True ) . Donc, votre code esttry/except
gratuit, mais plus bas dans le framestack il y a (au moins) un tel bloc. Cela s'applique également aux autres fonctions ( y comprisos.path.isfile
).1.1. [Python]: pathlib.Chemin. is_file ()
- C'est un amateur (et plus python ic) de manipulation des chemins, mais
-
Sous le capot, il fait exactement la même chose ( pathlib.py , ligne ~#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]: Avec L'Énoncé De Contexte Gestionnaires . Soit:
-
Créer un:
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 usage - Je vais répliquer le comportement
isfile
(notez que c'est juste pour démontrer des buts, faire pas tentative d'écrire un tel 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
-
-
Utiliser [Python]: contextlib. supprimer ( *exceptions ) - qui était spécifiquement conçu pour supprimer sélectivement les exceptions
mais, ils semblent être enveloppants plus detry/except/else/finally
blocs, comme [Python]: le avec déclaration États:cela permet commun essayer ... sauf ... enfin modèles d'utilisation à encapsuler pour réutilisation pratique.
-
-
fonctions transversales du système de fichiers (et rechercher les résultats pour article(s) correspondant (s))
-
[os. listdir ( path=". ) (ou [Python]: os. scandir ( path=". ) on Python v 3.5 + )
- sous le capot, tous deux utilisent [man]: OPENDIR(3) / [man]: READDIR(3) / [homme: CLOSEDIR(3) ( [MSDN]: fonction FindFirstFile / [MSDN]: fonction FindNextFile / [MSDN]: fonction FindClose ) - via " ${PYTHON_SRC_DIR}/Modules/posixmodule.C"
en utilisant scandir () au lieu de listdir () peut augmenter de manière significative la performance du code qui nécessite également des informations sur le type de fichier ou l'attribut du fichier, car os.Les objets de DirEntry exposent cette information si le système d'exploitation la fournit lors de la numérisation d'un répertoire. Tous les os.Les méthodes DirEntry peuvent effectuer un système call, mais is_dir () et is_file () ne nécessitent habituellement qu'un appel système pour les liens symboliques; os.DirEntry.stat () nécessite toujours un appel système sur Unix mais n'en nécessite qu'un pour les liens symboliques sur Windows.
- [Python]: os. walk ( top, topdown=True, onerror = None, followlinks = False )
- Il utilise des
os.listdir
(os.scandir
lorsque disponible)
- Il utilise des
- [Python]: glob. iglob ( pathname, recursive= False ) ( [glob. glob ( chemin d'accès, * récursive=False ) )
- Ne semble pas une traversée de la fonction en soi (au moins dans certains cas), mais il utilise encore
os.listdir
- Ne semble pas une traversée de la fonction en soi (au moins dans certains cas), mais il utilise encore
puisque ces dossiers itérate over, (dans la plupart des cas) ils sont inefficaces pour notre problème (il y a des exceptions, comme non wildcarded glob bing - comme @ShadowRanger l'a souligné), donc je ne vais pas insister sur eux. Sans oublier que dans certains cas, le traitement du nom de fichier peut être nécessaire. -
-
[os. access ( path, 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 en raison de la 2 nd argument)- permissions de l'utilisateur pourrait restreindre le fichier "visibilité" comme le doc Unis:
...tester si l'utilisateur appelant a l'accès spécifié à chemin . mode doit être F_OK pour tester l'existence d'un chemin...
os.access("/tmp", os.F_OK)
puisque je travaille aussi dans C , j'utilise cette méthode aussi bien parce que 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 possible erreurs de l'utilisateur , et ce n'est pas comme Python ic que d'autres variantes. Ainsi, comme @AaronHall l'a fait remarquer à juste titre, ne l'utilisez que si vous savez ce que vous faites:
- Ux : [l'homme]: l'ACCÈS(2) (!!! payer attention à la note sur le trou de sécurité son utilisation pourrait introduire !!!)
- Win : [MSDN]: getfile Attributes function
Note : appeler natif API s est également possible via [Python]: ctypes - une bibliothèque de fonction étrangère pour Python , mais en la plupart des cas, c'est plus compliqué.
( Win spécifique): Depuis msvcr* ( vcruntime* ) exportations [MSDN]: _access, _waccess la fonction de la famille, 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", os.F_OK) -1
Notes :
- bien que ce ne soit pas un bonne pratique, j'utilise
os.F_OK
dans l'appel, mais c'est juste pour la clarté (sa valeur est 0 ) - j'utilise
_waccess
de sorte que le même code fonctionne sur Python3 et Python2 (malgré unicode différences liées entre eux) - bien que cela vise une zone très spécifique, il n'a pas été mentionné dans l'un des précédents réponses
la contrepartie Lnx ( Ubtu (16 x64) ) ainsi: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"/tmp1", os.F_OK) -1
Notes :
-
"place hardcoding libc 's path ( " /lib/x86_64-linux-gnu/libc.alors?6" ) qui peut (et très probablement, va) varier d'un système à l'autre,
None
(ou la chaîne vide) peut être passé au constructeurCDLL
(ctypes.CDLL(None).access(b"/tmp", os.F_OK)
). Selon [man]: DLOPEN (3) :si filename est nul, alors la poignée retournée est pour le main programme. Lorsqu'elle est donnée à dlsym (), cette poignée provoque une recherche d'un symbole dans le programme principal, suivi par tous les objets partagés chargé à démarrage du programme, puis tous les objets partagés chargés par dlopen () avec le drapeau RTLD_GLOBAL .
- programme principal (courant) ( python ) est lié à libc , de sorte que ses symboles (y compris
access
) seront chargés - cela doit être manipulé avec soin, depuis 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 aussi à Win (mais ce n'est pas une si grande affaire, depuis msvcrt.dll est situé dans " %SystemRoot%\System32 " qui est dans %PATH% par défaut). Je voulais aller plus loin et reproduire ce comportement sur Win (et soumettre un patch), mais comme il s'avère, [MSDN]: GetProcAddress fonction only" sees " exported symboles, donc à moins que quelqu'un déclare les fonctions dans l'exécutable principal comme
__declspec(dllexport)
(pourquoi sur la Terre la régulier personne ferait cela?), le programme principal est chargeable mais pratiquement inutilisable
- programme principal (courant) ( python ) est lié à libc , de sorte que ses symboles (y compris
- permissions de l'utilisateur pourrait restreindre le fichier "visibilité" comme le doc Unis:
-
Installer environ 3 rd partie module avec les capacités du système de fichiers
très probablement, dépendra de l'une des façons ci-dessus (peut-être avec de légères personnalisations).
, en est Un exemple (encore une fois, Gagner "1519470920 spécifiques") [GitHub]: Python pour Windows (pywin32) Extensions , qui est un Python wrapper sur WINAPI .mais, comme c'est plutôt une solution, je m'arrête ici.
-
un Autre (lame) solution de contournement ( gainarie ) est (comme j'aime l'appeler), la sysadmin approche: utilisation de Python comme un 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
-
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
-
Bas de ligne :
- Faire utilisation
try
/except
/else
/finally
les blocs, car ils peuvent vous empêcher de courir dans une série de méchants problèmes. Un contre-exemple auquel je peux penser, est la performance: de tels blocs sont coûteux, alors essayez de ne pas les placer en code qu'il est supposé tourner des centaines de milliers de fois par seconde (mais puisque (dans la plupart des cas) il implique un accès disque, ce ne sera pas le cas).
Note(s) finale (s) :
- je vais essayer de le tenir à jour, toutes les suggestions sont les bienvenues, je vais incorporer rien utile qui viendra dans la réponse
C'est la façon la plus simple de vérifier si un fichier existe. Juste parce que le fichier existait quand vous avez coché ne garantie qu'il sera là quand vous avez besoin de 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+ possède 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 devez généralement) toujours utiliser un bloc try/except
lors de l'ouverture des fichiers:
try:
with p.open() as f:
# do awesome stuff
except OSError:
print('Well darn.')
le module pathlib a beaucoup de trucs cools: globbing pratique, vérification du propriétaire du fichier, chemin plus facile de rejoindre, etc. Il vaut la peine de vérifier. Si vous êtes sur un ancien 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 l'importer comme suit:
# Older Python versions
import pathlib2 as pathlib
préfère la déclaration try. Il est considéré comme un meilleur style et évite les conditions de course.
ne me croyez pas sur parole. Il y a beaucoup de soutien pour cette théorie. Voici un couple:
- Style: Section "Traitement des conditions inhabituelles" de http://allendowney.com/sd/notes/notes11.txt
- Eviter Les Conditions De Course
Comment puis-je 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 de fichier, et cochez la méthode is_file
(notez que ceci retourne vrai pour les liens symboliques pointant vers les fichiers réguliers aussi bien):
>>> 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 rétroporter le module pathlib de pypi, pathlib2
, ou bien cochez 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 y a la possibilité d'une condition de race (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.
Parce Que Python utilise try
partout, il n'y a vraiment aucune raison d'éviter une implémentation qui l'utilise.
mais le reste de cette réponse tente de considérer ces mises en garde.
réponse plus longue, Beaucoup plus pédante
Disponible depuis Python 3.4, utilisez le nouvel objet Path
dans pathlib
. Notez que .exists
n'est pas tout à fait correct, parce que les répertoires ne sont pas des fichiers (sauf dans le sens unix que 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 allons chercher 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 fermé (et le ferme automatiquement lorsqu'il n'y a plus de références).
>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False
Si vous creusez dans la mise en œuvre , 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
parce qu'il évite les conditions de course. Avec try
, vous tentez simplement de lire votre fichier, en vous attendant à ce qu'il soit là, et si ce n'est pas le cas, vous attrapez l'exception et exécutez tout comportement de repli qui a du sens.
Si vous voulez vérifier qu'un fichier existe avant que vous n'essayiez de le lire, et que vous le supprimiez et que vous utilisiez plusieurs threads ou processus, ou qu'un autre programme sache à propos de ce fichier et pourrait le supprimer - vous risquez la possibilité d'un condition de course si vous vérifiez qu'il existe, parce que vous êtes alors course de l'ouvrir avant que son condition (son existence) change.
les conditions de course sont très difficiles à déboguer parce qu'il y a une très petite fenêtre dans laquelle ils peuvent causer l'échec de votre programme.
mais si c'est votre motivation, vous pouvez obtenir la valeur d'un try
déclaration en utilisant le suppress
gestionnaire de contexte.
éviter les conditions de course sans déclaration d'essai: suppress
Python 3.4 nous donne le suppress
context manager (auparavant le ignore
context manager), qui fait sémantiquement exactement la même chose en moins de lignes, tout en rencontrant également (au moins superficiellement) la demande originale d'éviter une try
déclaration:
from contextlib import suppress
from pathlib import Path
Utilisation:
>>> with suppress(OSError), Path('doesnotexist').open() as f:
... for line in f:
... print(line)
...
>>>
>>> with suppress(OSError):
... Path('doesnotexist').unlink()
...
>>>
pour les Pythons plus anciens, vous pouvez lancer votre propre suppress
, mais sans un try
sera plus verbeux qu'avec. Je crois que c'est en fait la seule réponse cela n'utilise pas try
à n'importe quel niveau dans le Python qui peut être appliqué avant Python 3.4 parce qu'il utilise un gestionnaire de contexte à la place:
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 essayer":
isfile
import os
os.path.isfile(path)
de la docs :
os.path.isfile(path)
retourner True si path est un fichier régulier existant. Cela suit symboliquement liens, donc les deux
islink()
etisfile()
peuvent être vrais pour le même chemin.
mais si vous examinez la source de cette fonction, vous verrez qu'elle 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
tous il utilise le chemin donné pour voir s'il peut obtenir des statistiques dessus, en attrapant OSError
et en vérifiant si c'est un fichier s'il n'a pas soulevé l'exception.
si vous avez l'intention de faire quelque chose avec le fichier, je vous suggérerais de le tenter directement avec un essai-sauf pour éviter une condition de course:
try:
with open(path) as f:
f.read()
except OSError:
pass
os.accès
Disponible pour Unix et Windows est os.access
, mais pour vous doit passer des drapeaux, et il ne fait pas de différence entre les fichiers et les répertoires. Ceci est plus utilisé pour tester si l'utilisateur réel qui invoque a accès dans un environnement de privilège élevé:
import os
os.access(path, os.F_OK)
il souffre également des mêmes problèmes de condition de race que isfile
. Du docs :
Note: Utiliser access () pour vérifier si un utilisateur est autorisé à ouvrir un fichier par exemple avant de le faire en utilisant open() crée un trou de sécurité, car l'utilisateur pourrait exploiter le court laps de temps entre la vérification et ouvrir le fichier pour le manipuler. Il est préférable d'utiliser L'EAFP technique. 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()
éviter d'utiliser os.access
. C'est une fonction de bas niveau qui a plus de possibilités d'erreur Utilisateur que les objets et les fonctions de haut niveau discutés ci-dessus.
la Critique de l'autre de répondre:
une autre réponse dit ceci à propos de os.access
:
personnellement, je préfère celui-ci car sous le capot, il appelle les API natives (via "${PYTHON_SRC_DIR}/Modules/posixmodule.c"), mais il ouvre également une porte pour d'éventuelles erreurs utilisateur, et il n'est pas aussi pythonique que d'autres variantes:
cette réponse dit qu'il préfère un non-Pythonic, méthode sujette à erreur, sans justification. Il semble encourager les utilisateurs à utiliser des IPA de faible niveau sans les comprendre.
il crée aussi un gestionnaire de contexte qui, en retournant inconditionnellement True
, autorise toutes les Exceptions (y compris KeyboardInterrupt
et SystemExit
!) pour passer silencieusement, ce qui est une bonne façon de cacher 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!"
importer os
rend plus facile de naviguer et d'effectuer des actions standard avec votre système d'exploitation.
, Pour référence, voir aussi Comment faire pour vérifier si un fichier existe à l'aide de Python?
si vous avez besoin d'opérations de haut niveau, utilisez shutil
.
Test des fichiers et des dossiers os.path.isfile()
, os.path.isdir()
et os.path.exists()
en supposant que le "chemin" est un chemin valide, ce tableau montre ce qui est retourné par chaque fonction pour les fichiers et 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 la meilleure façon est encore d'utiliser os.path.isfile
:
>>> os.path.isfile('/path/to/some/file.txt')
ou en Python 3 vous pouvez utiliser pathlib
:
import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
...
il ne semble pas qu'il y ait une différence fonctionnelle significative entre try/except et isfile()
, donc vous devriez utiliser lequel a du sens.
Si vous voulez lire un fichier, s'il existe, ne
try:
f = open(filepath)
except IOError:
print 'Oh dear.'
mais si vous vouliez simplement renommer un fichier s'il existe, et donc ne pas avoir besoin de l'ouvrir, faites
if os.path.isfile(filepath):
os.rename(filepath, filepath + '.old')
Si vous voulez écrire dans un fichier, s'il n'existe pas, faire
# 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 différent.
, Vous pouvez essayer ce (safer):
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] No such file or directory: 'quoi que ce soit.txt')
alors, selon le résultat, votre programme peut simplement continuer à courir de là ou vous pouvez coder pour l'arrêter si vous voulez.
bien que je recommande toujours d'utiliser try
et except
déclarations, voici quelques possibilités pour vous (mon préféré est d'utiliser os.access
):
-
essayez d'ouvrir le fichier:
ouvrir le fichier vérifiera toujours l'existence du fichier. Vous pouvez faire une fonction comme:
def File_Existence(filepath): f = open(filepath) return True
S'il est faux, il arrêtera l'exécution avec un IOError sans penchant ou OSError dans les versions ultérieures de Python. Pour attraper l'exception, vous devez utiliser une clause d'essai. Bien sûr, vous pouvez toujours utilisez un
try
sauf 'déclaration comme ainsi (merci à 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
-
Utiliser
os.path.exists(path)
:ceci vérifiera l'existence de ce que vous spécifiez. Cependant, il vérifie pour les fichiers et répertoires donc attention à comment vous l'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
-
Utiliser
os.access(path, mode)
:ceci vérifiera si vous avez accès au fichier. Il va vérifier les autorisations. D'après le rapport os.py documentation, en tapant
os.F_OK
, il vérifiera l'existence du chemin. Cependant, cela créera un trou de sécurité, car quelqu'un peut attaquer votre fichier en utilisant le temps entre la vérification des permissions et l'ouverture du fichier. Vous devriez plutôt aller directement à l'ouverture du fichier au lieu de vérifier les permissions. ( EAFP vs LBYP ). Si vous n'allez pas ouvrir le fichier après, et seulement vérifier son existence, alors vous pouvez utiliser ceci.en tout cas, ici:
>>> import os >>> os.access("/is/a/file.txt", os.F_OK) True
je dois aussi mentionner qu'il y a deux façons que vous ne serez pas en mesure de vérifier l'existence d'un fichier. La question 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 que vous puissiez déterminer votre problème. J'espère que cela aide! :)
en Python 3.4 la langue fournit un nouveau module pour gérer les fichiers:
import pathlib
path = pathlib.Path('path/to/file')
if path.is_file(): # If you want to check a directory: path.is_dir()
# If it is true, return true on your code.
Si le fichier est pour l'ouverture, vous pouvez utiliser 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!')
mise à jour
juste pour éviter la confusion et basé sur les réponses que j'ai eu, réponse courante trouve soit un fichier ou un répertoire avec 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"
la levée d'exceptions est considérée comme acceptable, et Pythonic, approche pour le contrôle de flux dans votre programme. Envisager la manipulation manquant dossiers avec IOErrors. Dans ce cas, une exception de IOError sera soulevée si le fichier existe, mais l'utilisateur ne dispose pas des autorisations de lecture.
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 versions plus anciennes, vous pouvez rapidement écrire votre propre suppression:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
Voici une commande 1 ligne Python pour L'environnement en ligne de commande Linux. Je trouve ça très pratique vu que je ne suis pas un mec sexy.
python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"
j'espère que c'est utile.
en ajoutant une autre légère variation qui ne se reflète pas exactement dans les autres réponses.
ce sera gérer le cas de la file_path
étant None
ou 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
ajout d'une variante basée sur la suggestion de Shahbaz
def file_exists(file_path):
if not file_path:
return False
else:
return os.path.isfile(file_path)
ajout d'une variante basée sur la suggestion de Peter Wood
def file_exists(file_path):
return file_path and os.path.isfile(file_path):
vérifier l'existence d'un fichier ou d'un répertoire
vous pouvez suivre ces trois voies:
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é à la fois 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()
je suis l'auteur d'un paquet qui existe depuis environ 10 ans, et qui a une fonction qui répond directement à cette question. Fondamentalement, si vous êtes sur un système non-Windows, il utilise Popen
pour accéder à find
. Cependant, si vous êtes sur Windows, il réplique find
avec un système de fichiers efficace walker.
le code lui-même n'utilise pas de bloc try
... sauf pour déterminer le système d'exploitation et donc vous orienter vers le style "Unix" find
ou le bouton à main find
. Les tests de synchronisation ont montré que le try
était plus rapide dans la détermination de L'OS, donc j'ai utilisé un là (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 regarder, est ici: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190
Date: 2017-12-04
toutes les solutions possibles ont été énumérées dans d'autres réponses.
une façon intuitive et argumentée de vérifier si un fichier existe est la suivante:
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 un cheatsheet exhaustif 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']}
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
Comment puis-je vérifier si un fichier existe, sans utiliser la déclaration try?
en 2016, c'est sans doute la façon la plus facile 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
est en fait juste une méthode d'aide qui utilise à l'interne os.stat
et stat.S_ISREG(mode)
ci-dessous. Cette os.stat
est une méthode de niveau inférieur qui vous fournira informations détaillées sur les fichiers, répertoires, sockets, buffers, et plus encore. plus d'informations sur os.stat ici
Note: cependant, cette approche ne verrouillera pas le fichier de quelque manière que ce soit et donc votre code peut devenir vulnérable aux bogues" time of check to time of use " ( TOCTTOU ).
donc soulever des exceptions est considéré comme acceptable, et Pythonic, approche pour le contrôle de flux dans votre programme. Et on devrait envisager de traiter les fichiers manquants avec IOErrors, plutôt que if
( juste un conseil ).
Si vous avez importé NumPy déjà pour d'autres fins, il n'est pas nécessaire d'importer d'autres bibliothèques, comme pathlib
, os
, paths
, etc.
import numpy as np
np.DataSource().exists("path/to/your/file")
ceci retournera vrai ou faux basé sur son existence.