Réponses:
Si la raison pour laquelle vous vérifiez est que vous pouvez faire quelque chose comme if file_exists: open_it(), il est plus sûr d'utiliser un tryautour pour tenter de l'ouvrir. La vérification puis l'ouverture risquent de supprimer ou de déplacer le fichier ou quelque chose entre le moment où vous vérifiez 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
Renvoie
Truesi le chemin est un fichier standard existant. Cela suit les liens symboliques, donc islink () et isfile () peuvent être vrais 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 pathlibmodule propose une approche orientée objet (rétroportée pathlib2en 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, procédez comme suit:
if my_file.is_dir():
# directory exists
Pour vérifier si un Pathobjet 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 trybloc:
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
FileNotFoundErrorété introduit dans Python 3. Si vous devez également prendre en charge Python 2.7 ainsi que Python 3, vous pouvez utiliser à la IOErrorplace (quelles FileNotFoundErrorsous-classes) stackoverflow.com/a/21368457/1960959
open('file', 'r+')) puis rechercher jusqu'à la fin.
Vous avez la os.path.existsfonction:
import os.path
os.path.exists(file_path)
Cela renvoie Trueà la fois pour les fichiers et les répertoires mais vous pouvez utiliser à la place
os.path.isfile(file_path)
pour tester si c'est un fichier en particulier. Il suit les liens symboliques.
Contrairement isfile(), exists()reviendra Truepour les répertoires. Donc, selon que vous souhaitez uniquement des fichiers simples ou également des répertoires, vous utiliserez isfile()ou exists(). Voici une sortie REPL simple:
>>> os.path.isfile("/etc/password.txt")
True
>>> os.path.isfile("/etc")
False
>>> os.path.isfile("/does/not/exist")
False
>>> os.path.exists("/etc/password.txt")
True
>>> os.path.exists("/etc")
True
>>> os.path.exists("/does/not/exist")
False
Utiliser os.path.isfile()avec os.access():
import os
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")
os.access()renvoie false.
import os, vous n'en avez plus besoin import os.pathcar il en fait déjà partie os. Vous avez juste besoin d'importer os.pathsi vous n'utilisez que des fonctions depuis os.pathet non de oslui-même, pour importer une chose plus petite, mais comme vous utilisez os.accesset os.R_OK, la deuxième importation n'est pas nécessaire.
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 toutes les manières possibles aient été répertoriées dans (au moins une des) réponses existantes (par exemple, des éléments spécifiques à Python 3.4 ont été ajoutés), je vais essayer de tout regrouper.
Remarque : chaque morceau de code de bibliothèque standard Python que je vais publier appartient à la version 3.5.3 .
Énoncé du problème :
Solutions possibles :
[Python 3]: os.path. EXISTE ( chemin ) (vérifier également d' autres membres de la famille des fonctions comme os.path.isfile, os.path.isdir, os.path.lexistsdes comportements légèrement différents)
os.path.exists(path)
Renvoie
Truesi chemin fait référence à un chemin existant ou à un descripteur de fichier ouvert. RenvoieFalseles liens symboliques rompus. Sur certaines plates-formes, cette fonction peut retournerFalsesi l'autorisation n'est pas accordée pour exécuter os.stat () sur le fichier demandé, même si le chemin existe physiquement.
Tout va bien, mais si vous suivez l'arborescence 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 Truec'est juste un bloc try / except autour de [Python 3]: os. stat ( path, *, dir_fd = None, follow_symlinks = True ) . Donc, votre code est try / except free, mais plus bas dans la framestack il y a (au moins) un tel bloc. Cela s'applique également à d'autres fonctions ( y compris os.path.isfile ).
1.1. [Python 3]: Chemin. is_file ()
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 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 os.path.isfilecomportement (notez que c'est juste à des fins de démonstration, n'essayez pas d'écrire un tel code pour la 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 resultUtilisez [Python 3]: contextlib. supprimer ( * exceptions ) - qui a été spécialement conçu pour supprimer sélectivement les exceptions
Mais, ils semblent être des wrappers sur les blocs try / except / else / finally , comme [Python 3]: L' instruction with indique:
Cela permet d' essayer ... sauf ... enfin, les modèles d'utilisation à encapsuler pour une réutilisation pratique.
Fonctions de traversée du système de fichiers (et recherchez les éléments correspondants dans les résultats)
[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 nécessite également des informations sur le type ou l'attribut de fichier, car les objets os.DirEntry 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écessitent généralement un appel système uniquement pour les liens symboliques; os.DirEntry.stat () nécessite toujours un appel système sous Unix mais n'en requiert qu'un pour les liens symboliques sous Windows.
os.listdir( os.scandirsi disponible)glob.glob)
os.listdir
Étant donné que ces itérations sur les dossiers, (dans la plupart des cas), elles sont inefficaces pour notre problème (il existe des exceptions, comme le glob bing non générique - comme l'a souligné @ShadowRanger), donc je ne vais pas insister sur eux. Sans oublier que dans certains cas, le traitement des noms de fichiers peut être requis.
[Python 3]: os. access ( path, mode, *, dir_fd = None, effective_ids = False, follow_symlinks = True ) dont le comportement est proche os.path.exists(en fait, il est plus large, principalement à cause du 2 ème argument)
... teste si l'utilisateur appelant a l'accès spécifié au chemin . le mode devrait être F_OK pour tester l'existence du chemin ...
os.access("/tmp", os.F_OK)
Depuis que je aussi travailler en C , j'utilise cette méthode ainsi que sous le capot, il appelle native API s (encore une fois, par « $ {} PYTHON_SRC_DIR /Modules/posixmodule.c » ), mais il ouvre aussi une porte pour un éventuel utilisateur erreurs , et ce n'est pas aussi Python ic que les autres variantes. Donc, comme @AaronHall l'a souligné à juste titre, ne l'utilisez que si vous savez ce que vous faites:
Remarque : appeler des API natives 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é.
( Spécifique à Win ): Étant donné que vcruntime * ( msvcr * ) .dll exporte également une famille de fonctions [MS.Docs]: _access, _waccess , 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
Remarques :
os.F_OKdans l'appel, mais c'est juste pour plus de clarté (sa valeur est 0 )
La contrepartie 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
Remarques :
Au lieu de cela, codez en dur le chemin de libc ( "/lib/x86_64-linux-gnu/libc.so.6" ) qui peut (et très probablement, variera) d'un système à l'autre, Aucun (ou la chaîne vide) peut être transmis au constructeur CDLL ( ctypes.CDLL(None).access(b"/tmp", os.F_OK)). Selon [man7]: DLOPEN (3) :
Si le nom de fichier est NULL, le descripteur renvoyé correspond au programme principal. Lorsqu'il est donné à dlsym (), ce handle provoque une recherche d'un symbole dans le programme principal, suivi de tous les objets partagés chargés au démarrage du programme, puis de tous les objets partagés chargés par dlopen () avec l'indicateur RTLD_GLOBAL .
__declspec(dllexport)(pourquoi diable la personne ordinaire ferait ça?), le programme principal est chargeable mais quasiment inutilisableInstaller un module tiers avec des capacités de système de fichiers
Très probablement, s'appuiera sur l'une des méthodes ci-dessus (peut-être avec de légères personnalisations).
Un exemple serait (encore une fois, spécifique à Win ) [GitHub]: mhammond / pywin32 - Extensions Python pour Windows (pywin32) , qui est un wrapper Python sur les WINAPI .
Mais, puisque cela ressemble plus à une solution de contournement, je m'arrête ici.
Une autre solution (boiteuse) ( gainarie ) est (comme j'aime l'appeler) l' approche sysadmin : utiliser Python comme wrapper pour exécuter des commandes shell
Gagner :
(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 (s) finale (s) :
glob.iglob(et glob.globaussi) sont basés suros.scandir , donc c'est paresseux maintenant; pour obtenir le premier hit dans un répertoire de 10 millions de fichiers, vous scannez uniquement jusqu'à ce que vous atteigniez le premier hit. Et même avant la version 3.6, si vous utilisez des globméthodes sans caractères génériques, la fonction est intelligente: elle sait que vous ne pouvez avoir qu'un seul hit, ce qui simplifie le globbing à juste os.path.isdirouos.path.lexists (selon que le chemin se termine /).
os.path.isdirou os.path.lexistpuisqu'il s'agit d'un groupe d'appels de fonction de niveau Python et d'une chaîne avant de décider que le chemin efficace est viable, mais aucun appel système supplémentaire ni travail d'E / S, ce qui est beaucoup plus lent).
C'est le moyen le plus simple de vérifier si un fichier existe. Le fait que le fichier existait lorsque vous avez vérifié ne garantit pas qu'il sera là lorsque vous aurez 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 try/exceptbloc lors de l'ouverture de fichiers:
try:
with p.open() as f:
# do awesome stuff
except OSError:
print('Well darn.')
Le module pathlib contient beaucoup de choses intéressantes: globbing pratique, vérification du propriétaire du fichier, jointure de chemin plus facile, etc. Cela vaut la peine d'être vérifié. Si vous utilisez 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
Importez-le ensuite comme suit:
# Older Python versions
import pathlib2 as pathlib
Préférez l'instruction 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. En voici deux:
try...exceptne permet pas de résoudre ce problème de toute façon.
except:clause fera qu'une exception apparaissant dans cette partie de votre code lèvera un message déroutant (deuxième erreur levée pendant le traitement du premier.)
Comment vérifier si un fichier existe, en utilisant Python, sans utiliser une instruction try?
Désormais disponible depuis Python 3.4, importez et instanciez un Pathobjet avec le nom de fichier, et vérifiez la is_fileméthode (notez que cela renvoie True pour les liens symboliques pointant également vers des 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 rétroporter le module pathlib à partir de pypi pathlib2, ou sinon vérifier à isfilepartir du os.pathmodule:
>>> 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 concurrence (en fonction de ce que vous essayez d'accomplir) et du fait que l'implémentation sous-jacente utilise un try, mais Python utilise trypartout dans son implémentation.
Parce que Python utilise trypartout, il n'y a vraiment aucune raison d'éviter une implémentation qui l'utilise.
Mais le reste de cette réponse tente de tenir compte de ces mises en garde.
Disponible depuis Python 3.4, utilisez le nouvel Pathobjet dans pathlib. Notez que ce .existsn'est pas tout à fait raison, car 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, obtenons 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, NamedTemporaryFilesupprime 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 , vous verrez que cela is_fileutilise 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
On aime tryparce que ça évite les conditions de course. Avec try, vous essayez simplement de lire votre fichier, en vous attendant à ce qu'il soit là, et sinon, vous interceptez l'exception et effectuez le comportement de secours qui a du sens.
Si vous souhaitez vérifier qu'un fichier existe avant d'essayer de le lire, que vous le supprimiez et que vous utilisiez plusieurs threads ou processus, ou qu'un autre programme connaisse ce fichier et puisse le supprimer - vous risquez de une condition de course si vous vérifiez qu'elle existe, car vous êtes alors en course pour l'ouvrir avant que sa condition (son existence) ne change.
Les conditions de concurrence 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 trydéclaration en utilisant le suppressgestionnaire de contexte.
suppressPython 3.4 nous donne le suppressgestionnaire de contexte (anciennement le ignoregestionnaire de contexte), qui fait sémantiquement exactement la même chose en moins de lignes, tout en répondant (au moins superficiellement) à la demande d'origine pour éviter une trydéclaration:
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 pouvez lancer le vôtre suppress, mais sans tryvolonté sera plus verbeux qu'avec. Je crois que c'est en fait la seule réponse qui n'utilise tryà aucun niveau dans Python qui peut être appliquée avant Python 3.4 car elle 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
isfile
import os
os.path.isfile(path)
à partir des documents :
os.path.isfile(path)Renvoie True si le chemin est un fichier standard existant. Cela suit les liens symboliques, 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
Tout ce qu'il fait, c'est utiliser le chemin donné pour voir s'il peut obtenir des statistiques dessus, attraper OSErrorpuis vérifier s'il s'agit d'un fichier s'il n'a pas levé l'exception.
Si vous avez l'intention de faire quelque chose avec le fichier, je vous suggère d'essayer directement avec un essai, sauf pour éviter une condition de concurrence:
try:
with open(path) as f:
f.read()
except OSError:
pass
os.access
Disponible pour Unix et Windows os.access, mais pour l'utiliser, vous devez passer des drapeaux et cela ne fait pas de différence entre les fichiers et les répertoires. Ceci est plus utilisé pour tester si le véritable utilisateur appelant 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 documentation :
Remarque: Utiliser access () pour vérifier si un utilisateur est autorisé par exemple à ouvrir un fichier avant de le faire en utilisant open () crée une faille 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 qui présente plus de possibilités 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 sous le capot, il appelle des API natives (via "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), mais il ouvre également une porte pour d'éventuelles erreurs utilisateur, et ce n'est pas aussi Pythonic que les autres variantes :
Cette réponse indique qu'elle préfère une méthode non pythonique, sujette aux erreurs, sans justification. Il semble encourager les utilisateurs à utiliser des API de bas niveau sans les comprendre.
Il crée également un gestionnaire de contexte qui, en retournant sans condition True, permet à toutes les exceptions (y compris KeyboardInterruptet SystemExit!) De passer silencieusement, 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 osfacilite la navigation et l'exécution d'actions standard avec votre système d'exploitation.
Pour référence, voir également Comment vérifier si un fichier existe en utilisant Python?
Si vous avez besoin d'opérations de haut niveau, utilisez shutil.
os.path.existsrenvoie true pour les éléments qui ne sont pas des fichiers, tels que les répertoires. Cela donne des faux positifs. Voir les autres réponses qui recommandent os.path.isfile.
Test des fichiers et des dossiers avec os.path.isfile(), os.path.isdir()etos.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 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 est toujours 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():
...
pathlibest la solution OOP de python pour les chemins. Vous pouvez en faire beaucoup plus. Si vous avez juste besoin de vérifier l'existence, l'avantage n'est pas si grand.
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 souhaitez lire un fichier, s'il existe, faites
try:
f = open(filepath)
except IOError:
print 'Oh dear.'
Mais si vous voulez simplement renommer un fichier s'il existe et que vous n'avez donc pas 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, 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.
os.path.existsrenvoie true pour les éléments qui ne sont pas des fichiers, tels que les répertoires. Cela donne des faux positifs. Voir les autres réponses qui recommandent os.path.isfile.
filepathavec le bon timing, et BAM , vous écrasez le fichier cible. Vous devriez le faire open(filepath, 'wx')dans un try...exceptbloc pour éviter le problème.
OSErrorsi filepath + '.old'existe déjà: "Sous Windows, si dst existe déjà, OSError sera déclenchée même s'il s'agit d'un fichier; il n'y a peut-être aucun moyen d'implémenter un renom atomique lorsque dst nomme un fichier existant. "
os.replace effectue de manière portative le remplacement silencieux du fichier de destination (il est identique au os.renamecomportement de Linux) (il ne fait d'erreur que si le nom de destination existe et est un répertoire). Vous êtes donc bloqué sur 2.x, mais les utilisateurs de Py3 ont une bonne option depuis plusieurs années maintenant.
renameexemple: Cela devrait toujours être fait avec try/ except. os.rename(ou os.replacesur Python moderne) est atomique; le faire vérifier puis renommer introduit une course inutile et des appels système supplémentaires. try: os.replace(filepath, filepath + '.old') except OSError: pass
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))
Le résultat serait:
([Errno 2] Aucun fichier ou répertoire de ce type: 'que ce soit.txt')
Ensuite, selon le résultat, votre programme peut simplement continuer à fonctionner à partir de là ou vous pouvez coder pour l'arrêter si vous le souhaitez.
try
Bien que je recommande toujours d'utiliser les instructions tryet except, voici quelques possibilités pour vous (mon préféré est d'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
S'il est faux, il arrêtera l'exécution avec une erreur IOError ou OSError non gérée dans les versions ultérieures de Python. Pour intercepter l'exception, vous devez utiliser une clause try except. Bien sûr, vous pouvez toujours utiliser une tryinstruction except comme ceci (merci à hsandt
de 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 TrueUtilisation 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 faites attention à 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")
FalseUtilisation os.access(path, mode):
Cela vérifiera si vous avez accès au fichier. Il vérifiera les autorisations. Sur la base de la documentation os.py, en tapant os.F_OK, il vérifiera l'existence du chemin. Cependant, son utilisation créera une faille de sécurité, car quelqu'un peut attaquer votre fichier en utilisant le temps 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 contre LBYP ). Si vous n'ouvrez pas le fichier par la suite et ne vérifiez que son existence, vous pouvez l'utiliser.
Bref, ici:
>>> import os
>>> os.access("/is/a/file.txt", os.F_OK)
TrueJe dois également mentionner qu'il existe deux manières de ne pas pouvoir vérifier l'existence d'un fichier. Soit le problème sera permission deniedou no such file or directory. Si vous attrapez un IOError, définissez le IOError as e(comme ma première option), puis saisissez-le print(e.args)afin que vous puissiez, espérons-le, déterminer votre problème. J'espère que ça aide! :)
Date: 2017-12-04
Chaque solution possible a été répertoriée dans d'autres réponses.
Un moyen intuitif et discutable de vérifier si un fichier existe est le suivant:
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']}
Si le fichier est destiné à être ouvert, 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!')
MISE À JOUR
Juste pour éviter toute confusion et sur la base des réponses que j'ai obtenues, la réponse actuelle trouve soit un fichier soit un répertoire avec le nom donné.
os.path.existsrenvoie true pour les éléments qui ne sont pas des fichiers, tels que les répertoires. Cela donne des faux positifs. Voir les autres réponses qui recommandent os.path.isfile.
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 une approche acceptable et Pythonique pour le contrôle de flux dans votre programme. Pensez à gérer les fichiers manquants avec IOErrors. Dans cette situation, une exception IOError sera déclenchée si le fichier existe mais que 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()
suppressfait 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
Je suis l'auteur d'un paquet qui existe depuis environ 10 ans, et il a une fonction qui répond directement à cette question. Fondamentalement, si vous êtes sur un système non Windows, il utilise Popenpour y accéder find. Cependant, si vous êtes sous Windows, il se réplique findavec un marcheur de système de fichiers efficace.
Le code lui-même n'utilise pas de trybloc… sauf pour déterminer le système d'exploitation et ainsi vous diriger vers le style "Unix" findou le hand-buillt find. Les tests de synchronisation ont montré qu'il tryétait plus rapide de déterminer le système d'exploitation, donc j'en ai utilisé un là-bas (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']
>>>
L'implémentation, si vous voulez regarder, est ici: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190
Vous pouvez suivre ces trois façons:
Remarque 1:
os.path.isfileutilisé uniquement pour les fichiers
import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists
Remarque 2:
os.path.existsutilisé 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
pathlib.Pathméthode (incluse dans Python 3+, installable avec pip pour Python 2)
from pathlib import Path
Path(filename).exists()
Ajout d'une autre légère variation qui ne se reflète pas exactement dans les autres réponses.
Cela gérera le cas de l' file_pathêtre Noneou de la 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 une 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 une suggestion de Peter Wood
def file_exists(file_path):
return file_path and os.path.isfile(file_path):
if (x) return true; else return false;est vraiment juste return x. Vos quatre dernières lignes peuvent devenir return os.path.isfile(file_path). Pendant que nous y sommes, la fonction entière peut être simplifiée comme return file_path and os.path.isfile(file_path).
return xdans le cas de if (x). Python considérera une chaîne vide comme Faux, auquel cas nous retournerions une chaîne vide au lieu d'un booléen. Le but de cette fonction est de toujours renvoyer bool.
xc'est os.path.isfile(..)donc déjà booléen.
os.path.isfile(None)soulève une exception, c'est pourquoi j'ai ajouté le chèque if. Je pourrais probablement l'envelopper dans un essai / sauf à la place, mais je pensais que c'était plus explicite de cette façon.
return file_path and os.path.isfile(file_path)
Voici une commande Python 1 ligne pour l'environnement de ligne de commande Linux. Je trouve cela TRÈS PRATIQUE car je ne suis pas un gars Bash si chaud.
python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"
J'espère que ceci est utile.
[ -f "${file}" ] && echo "file found" || echo "file not found"(qui est identique à if [ ... ]; then ...; else ...; fi).
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
os.path.existsrenvoie true pour les éléments qui ne sont pas des fichiers, tels que les répertoires. Cela donne des faux positifs. Voir les autres réponses qui recommandent os.path.isfile.
existsva bien. Si le but est de déterminer s'il est sûr d'ouvrir un fichier vraisemblablement existant, alors la critique est justifiée et existe n'est pas assez précise. Malheureusement, l'OP ne précise pas quel est l'objectif souhaité (et ne le fera probablement plus).
Comment vérifier si un fichier existe, sans utiliser l'instruction try?
En 2016, c'est sans doute la façon la 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
isfileest en fait juste une méthode d'aide qui utilise en interne os.statet en stat.S_ISREG(mode)dessous. Il os.stats'agit d'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. En savoir plus sur os.stat ici
Remarque: Cependant, cette approche ne verrouillera pas le fichier en aucune façon et donc votre code peut devenir vulnérable au " moment de la vérification au moment de l'utilisation " ( TOCTTOU bogues ).
Donc, lever des exceptions est considéré comme une approche acceptable et Pythonique pour le contrôle de flux dans votre programme. Et on devrait envisager de gérer les fichiers manquants avec IOErrors, plutôt que des ifinstructions ( juste un conseil ).
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)
isReadableFile(path,fileName)retournera Truesi le fichier est accessible et lisible par le processus \ program \ thread