Wie kann ich feststellen, ob eine Datei vorhanden ist oder nicht, ohne die Anweisung try
zu verwenden?
Wenn der Grund, den Sie überprüfen, so ist, dass Sie etwas wie if file_exists: open_it()
tun können, ist es sicherer, ein try
um den Versuch zu verwenden, es zu öffnen. Durch das Überprüfen und anschließende Öffnen kann die Datei gelöscht oder verschoben werden.
Wenn Sie die Datei nicht sofort öffnen möchten, können Sie os.path.isfile
verwenden
Gibt
True
zurück, wenn path eine vorhandene reguläre Datei ist. Dies folgt symbolischen Verknüpfungen, sodass sowohl islink () als auch isfile () für denselben Pfad gelten können.
_import os.path
os.path.isfile(fname)
_
wenn Sie sicher sein müssen, dass es sich um eine Datei handelt.
Ab Python 3.4 bietet das pathlib
-Modul einen objektorientierten Ansatz (rückportiert auf _pathlib2
_ in Python 2.7):
_from pathlib import Path
my_file = Path("/path/to/file")
if my_file.is_file():
# file exists
_
Gehen Sie wie folgt vor, um ein Verzeichnis zu überprüfen:
_if my_file.is_dir():
# directory exists
_
Um zu überprüfen, ob ein Path
-Objekt existiert, unabhängig davon, ob es sich um eine Datei oder ein Verzeichnis handelt, verwenden Sie exists()
:
_if my_file.exists():
# path exists
_
Sie können resolve(strict=True)
auch in einem try
-Block verwenden:
_try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
_
Du hast die os.path.exists
Funktion:
_import os.path
os.path.exists(file_path)
_
Dies gibt True
für Dateien und Verzeichnisse zurück, aber Sie können stattdessen verwenden
_os.path.isfile(file_path)
_
um zu testen, ob es sich um eine bestimmte Datei handelt. Es folgen Symlinks.
Im Gegensatz zu isfile()
gibt exists()
True
für Verzeichnisse zurück.
Je nachdem, ob Sie nur einfache Dateien oder auch Verzeichnisse möchten, verwenden Sie isfile()
oder exists()
. Hier ist eine einfache REPL Ausgabe.
>>> 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):
Verwenden Sie os.path.isfile()
mit 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
Obwohl in (mindestens einer) der vorhandenen Antworten fast jede mögliche Art aufgelistet wurde (z. B. wurde Python 3.4 spezifisches Material hinzugefügt), werde ich versuchen, alles zu gruppieren.
Hinweis: Jeder Teil des Python Standard-Bibliothekscodes, den ich veröffentlichen werde, gehört zur Version .5..
Problemstellung:
Mögliche Lösungen:
[Python 3]: os.path .existiert (path) (überprüfen Sie auch andere Funktionsfamilienmitglieder wie os.path.isfile
, os.path.isdir
, os.path.lexists
Für leicht abweichendes Verhalten)
os.path.exists(path)
Geben Sie
True
zurück, wenn path auf einen vorhandenen Pfad oder einen geöffneten Dateideskriptor verweist. GibtFalse
für unterbrochene symbolische Links zurück. Auf einigen Plattformen gibt diese Funktion möglicherweiseFalse
zurück, wenn keine Berechtigung zum Ausführen von os.stat () für die angeforderte Datei erteilt wurde, auch wenn path existiert physisch.
Alles in Ordnung, aber wenn Sie dem Importbaum folgen:
os.path
- posixpath.py (ntpath.py)
genericpath.py, Zeile ~ # 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
es ist nur ein try_/except Block um [Python 3]: os .stat ( path, *, dir_fd = Keine, follow_symlinks = True) . Ihr Code ist also try_/except frei, aber weiter unten im Framestack befindet sich (mindestens) eins ein solcher Block. Dies gilt auch für andere Funktionen (einschließlichos.path.isfile
).
1.1. [Python 3]: Pfad .is_file ()
Unter der Haube macht es gena dasselbe (pathlib.py, Zeile ~ # 133):
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]: Mit Anweisungskontextmanagern . Entweder:
Erstelle einen:
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 ...)
Und seine Verwendung - Ich werde das Verhalten os.path.isfile
Replizieren (beachten Sie, dass dies nur zu Demonstrationszwecken ist, versuchen Sie nicht, einen solchen Code für production zu schreiben):
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
Verwenden Sie [Python 3]: contextlib .suppress (* exceptions) - das specific wurde zum selektiven Unterdrücken von Ausnahmen entwickelt
Aber sie scheinen Deckblätter für try_/except_/else_ zu sein._/finally blocks, as [Python 3]: Die Anweisung with lautet:
Dies ermöglicht häufige Versuche ... mit Ausnahme von ... schließlich Verwendungsmustern zur bequemen Wiederverwendung gekapselt werden.
Funktionen zum Durchsuchen des Dateisystems (und Durchsuchen der Ergebnisse nach übereinstimmenden Elementen)
[Python 3]: os .listdir (path = '.') (oder [Python 3] : os .scandir (path = '.') on Python v .5 +, backport: [PyPI]: Scandir )
Unter der Haube verwenden beide:
via [GitHub]: python/cpython - (master) cpython/Modules/posixmodule.c
Durch die Verwendung von scandir () anstelle von listdir () kann die Leistung von Code erheblich gesteigert werden, der auch Dateityp- oder Dateiattributinformationen benötigt. weil os.DirEntry -Objekte diese Informationen verfügbar machen, wenn das Betriebssystem sie beim Scannen eines Verzeichnisses bereitstellt. Alle os.DirEntry -Methoden können einen Systemaufruf ausführen, aber is_dir () und is_file () erfordern normalerweise nur einen Systemaufruf für symbolische Verknüpfungen; os.DirEntry.stat () erfordert unter Unix immer einen Systemaufruf, unter Windows jedoch nur einen für symbolische Verknüpfungen.
os.listdir
(os.scandir
, Wenn verfügbar)glob.glob
) os.listdir
Da diese über Ordner iterieren (in den meisten Fällen), sind sie für unser Problem ineffizient (es gibt Ausnahmen, wie z. B. glob bing ohne Platzhalterzeichen - wie @ShadowRanger hervorhob), also bin ich Ich werde nicht darauf bestehen. Ganz zu schweigen davon, dass in einigen Fällen eine Dateinamenverarbeitung erforderlich sein kann.
[Python 3]: os .access (path, mode, *, dir_fd = Keine, effective_ids = False, follow_symlinks = True) wessen Verhalten ist in der Nähe von os.path.exists
(eigentlich ist es breiter, hauptsächlich wegen der 2nd Streit)
... testen, ob der aufrufende Benutzer den angegebenen Zugriff auf path hat. mode sollte F_OK sein, um die Existenz des Pfades zu testen ...
os.access("/tmp", os.F_OK)
Da ich auch in C arbeite, verwende ich diese Methode auch, weil sie unter der Haube native [~ # ~] api [~ # ~] aufruft ] s (erneut über "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), aber es öffnet auch ein Tor für mögliche Benutzerfehler, und es ist nicht so Python ic als andere Varianten. Also, wie @AaronHall richtig betont hat, benutze es nicht, wenn du nicht weißt, was du tust:
Hinweis: Aufrufen von nativen API s ist auch über [Python 3]: ctypes - A foreign möglich Funktionsbibliothek für Python , aber in den meisten Fällen ist es komplizierter.
(Win specific): Seit vcruntime * (msvcr *) .dll exportiert ein [MS.Docs] : _access, _waccess - Funktionsfamilie, hier ein Beispiel:
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
Anmerkungen:
os.F_OK
Im Aufruf, aber dies dient nur der Klarheit (sein Wert ist )
Das Gegenstück zu Lnx (btu (16 x 64)):
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
Anmerkungen:
Stattdessen wird der Pfad von libc hartcodiert ("/lib/x86_64-linux-gnu/libc.so.6"), der systemübergreifend variieren kann (und höchstwahrscheinlich wird). None (oder die leere Zeichenfolge) kann an den Konstruktor CDLL (ctypes.CDLL(None).access(b"/tmp", os.F_OK)
übergeben werden. Nach [man7]: DLOPEN (3) :
Wenn filename NULL ist, gilt das zurückgegebene Handle für das Hauptprogramm. Wenn dieses Handle an dlsym () übergeben wird, wird im Hauptprogramm nach einem Symbol gesucht, gefolgt von allen beim Programmstart geladenen gemeinsam genutzten Objekten und anschließend von allen gemeinsam genutzten Objekten, die von dlopen geladen wurden. () mit dem Flag RTLD_GLOBAL.
__declspec(dllexport)
(warum um alles in der Welt würde die regular Person das tun?), das Hauptprogramm ist ladbar aber ziemlich unbrauchbarInstallieren Sie ein Drittanbieter-Modul mit Dateisystemfunktionen
Am ehesten wird man sich auf einen der oben genannten Wege verlassen (evtl. mit leichten Anpassungen).
Ein Beispiel wäre (wieder Win spezifisch) [GitHub]: mhammond/pywin32 - Python für Windows (pywin32) Extensions , das ist ein Python Wrapper über WINAPI s.
Da dies jedoch eher eine Problemumgehung ist, höre ich hier auf.
Eine andere (lahme) Problemumgehung (gainarie) ist (wie ich es gerne nenne) der Ansatz sysadmin: Verwenden Sie Python als Wrapper, um Shell-Befehle auszuführen
Sieg:
(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 (bt)):
[[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))" 0 [[email protected]:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))" 512
Endeffekt:
Schlussnote (n):
Dies ist die einfachste Methode, um zu überprüfen, ob eine Datei vorhanden ist. Nur weil die Datei existierte, als Sie sie überprüft haben, nicht garantiert dass sie dort sein wird, wenn Sie sie öffnen müssen.
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 + verfügt über ein objektorientiertes Pfadmodul: pathlib . Mit diesem neuen Modul können Sie überprüfen, ob eine Datei wie folgt vorhanden ist:
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
Sie können (und sollten in der Regel auch weiterhin) einen try/except
-Block verwenden, wenn Sie Dateien öffnen:
try:
with p.open() as f:
# do awesome stuff
except OSError:
print('Well darn.')
Das pathlib-Modul enthält viele nützliche Funktionen: bequemes Verschieben von Daten, Überprüfen des Dateieigentümers, einfacheres Zusammenfügen von Pfaden usw. Es lohnt sich, dies zu überprüfen. Wenn Sie auf einem älteren Python (Version 2.6 oder höher) arbeiten, können Sie die pathlib weiterhin mit pip installieren:
# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2
Dann importiere es wie folgt:
# Older Python versions
import pathlib2 as pathlib
Bevorzugen Sie die try-Anweisung. Es gilt als besserer Stil und vermeidet Rennbedingungen.
Nimm mein Wort nicht dafür. Es gibt viel Unterstützung für diese Theorie. Hier ist ein paar:
Wie überprüfe ich mit Python, ob eine Datei vorhanden ist, ohne eine try-Anweisung zu verwenden?
Jetzt verfügbar seit Python 3.4, importieren und instanziieren Sie ein Path
-Objekt mit dem Dateinamen und überprüfen Sie die _is_file
_ -Methode (beachten Sie, dass dies auch True für Symlinks zurückgibt, die auf reguläre Dateien verweisen):
_>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False
_
Wenn Sie mit Python 2 arbeiten, können Sie das Pathlib-Modul von pypi, pathlib2
aus zurückportieren oder auf andere Weise isfile
aus dem Modul _os.path
_ prüfen:
_>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False
_
Das oben Gesagte ist wahrscheinlich die beste pragmatische direkte Antwort, aber es besteht die Möglichkeit einer Race-Bedingung (abhängig von dem, was Sie erreichen möchten) und der Tatsache, dass die zugrunde liegende Implementierung eine try
verwendet, aber Python. _ verwendet try
überall in seiner Implementierung.
Da Python try
überall verwendet, gibt es wirklich keinen Grund, eine Implementierung zu vermeiden, die es verwendet.
Der Rest dieser Antwort versucht jedoch, diese Vorbehalte zu berücksichtigen.
Verwenden Sie das neue Objekt Path
in pathlib
, das seit Python 3.4 verfügbar ist. Beachten Sie, dass _.exists
_ nicht ganz richtig ist, da Verzeichnisse keine Dateien sind (außer im Unix-Sinne, dass alles eine Datei ist).
_>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True
_
Also müssen wir _is_file
_ verwenden:
_>>> root.is_file()
False
_
Hier ist die Hilfe zu _is_file
_:
_is_file(self)
Whether this path is a regular file (also True for symlinks pointing
to regular files).
_
Lassen Sie uns eine Datei erhalten, von der wir wissen, dass sie eine Datei ist:
_>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True
_
Standardmäßig löscht NamedTemporaryFile
die Datei beim Schließen (und wird automatisch geschlossen, wenn keine Referenzen mehr vorhanden sind).
_>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False
_
Wenn Sie sich mit der Implementierung beschäftigen, werden Sie feststellen, dass _is_file
_ try
verwendet:
_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
_
Wir mögen try
, weil es Rennbedingungen vermeidet. Mit try
versuchen Sie einfach, Ihre Datei zu lesen, und erwarten, dass sie dort vorhanden ist. Andernfalls können Sie die Ausnahme abfangen und das sinnvolle Fallback-Verhalten ausführen.
Wenn Sie überprüfen möchten, ob eine Datei vorhanden ist, bevor Sie versuchen, sie zu lesen, und wenn Sie sie möglicherweise löschen und dann möglicherweise mehrere Threads oder Prozesse verwenden, oder wenn ein anderes Programm von dieser Datei Kenntnis hat und sie löschen könnte, besteht die Gefahr von eine Rennbedingung , wenn Sie überprüfen, ob sie existiert, weil Sie dann rennen , um sie zu öffnen, bevor ihre Bedingung (seine Existenz) ändert sich.
Rennbedingungen sind sehr schwer zu debuggen, da es ein sehr kleines Fenster gibt, in dem sie dazu führen können, dass Ihr Programm fehlschlägt.
Wenn dies Ihre Motivation ist, können Sie mithilfe des Kontextmanagers try
den Wert einer suppress
-Anweisung abrufen .
suppress
In Python 3.4 haben wir den Kontextmanager suppress
(früher ignore
), der in weniger Zeilen semantisch genau das Gleiche tut und gleichzeitig (zumindest oberflächlich) den Kontextmanager Original bitte, eine try
-Anweisung zu vermeiden:
_from contextlib import suppress
from pathlib import Path
_
Verwendungszweck:
_>>> with suppress(OSError), Path('doesnotexist').open() as f:
... for line in f:
... print(line)
...
>>>
>>> with suppress(OSError):
... Path('doesnotexist').unlink()
...
>>>
_
Für frühere Pythons könnten Sie Ihre eigenen suppress
rollen, aber ohne try
wird es wortreicher sein als mit. Ich glaube , dass dies tatsächlich die einzige Antwort ist, die try
auf keiner Ebene im Python verwendet , die vor Python 3.4, da stattdessen ein Kontextmanager verwendet wird:
_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)
_
Vielleicht einfacher mit einem Versuch:
_from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
_
isfile
_import os
os.path.isfile(path)
_
aus dem docs :
os.path.isfile(path)
Gibt True zurück, wenn path eine vorhandene reguläre Datei ist. Dies folgt symbolischen Verknüpfungen, sodass sowohl
islink()
als auchisfile()
für denselben Pfad gelten können.
Wenn Sie jedoch source dieser Funktion untersuchen, werden Sie feststellen, dass tatsächlich eine try-Anweisung verwendet wird:
_# 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
_
Alles, was es tut, ist, den angegebenen Pfad zu verwenden, um zu prüfen, ob Statistiken abgerufen werden können, OSError
abzufangen und dann zu prüfen, ob es sich um eine Datei handelt, wenn die Ausnahme nicht ausgelöst wurde.
Wenn Sie beabsichtigen, etwas mit der Datei zu tun, würde ich vorschlagen, sie direkt mit einem Versuch zu versuchen, außer um eine Racebedingung zu vermeiden:
_try:
with open(path) as f:
f.read()
except OSError:
pass
_
os.access
Verfügbar für Unix und Windows ist _os.access
_, aber zur Verwendung müssen Sie Flags übergeben, und es wird nicht zwischen Dateien und Verzeichnissen unterschieden. Dies wird eher verwendet, um zu testen, ob der tatsächlich aufrufende Benutzer in einer Umgebung mit erhöhten Rechten Zugriff hat:
_import os
os.access(path, os.F_OK)
_
Es hat auch die gleichen Probleme mit den Rennbedingungen wie isfile
. Aus dem docs :
Hinweis: Verwenden von access (), um zu überprüfen, ob ein Benutzer berechtigt ist, z. Öffnen einer Datei vor dem eigentlichen Öffnen mit open () führt zu einer Sicherheitslücke, da der Benutzer möglicherweise das kurze Zeitintervall zwischen dem Überprüfen und Öffnen der Datei ausnutzt, um sie zu manipulieren. Es ist vorzuziehen, EAFP-Techniken zu verwenden. Zum Beispiel:
_if os.access("myfile", os.R_OK): with open("myfile") as fp: return fp.read() return "some default data"
_ist besser geschrieben als:
_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()
_
Vermeiden Sie die Verwendung von _os.access
_. Es ist eine Funktion auf niedriger Ebene, die mehr Möglichkeiten für Benutzerfehler bietet als die oben diskutierten Objekte und Funktionen auf höherer Ebene.
Eine andere Antwort sagt dies über _os.access
_:
Persönlich bevorzuge ich dieses, weil es unter der Haube native APIs aufruft (über "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"), aber es öffnet auch ein Tor für mögliche Benutzerfehler und es ist nicht so pythonisch wie andere Varianten :
Diese Antwort besagt, dass es eine nicht-pythonische, fehleranfällige Methode ohne Rechtfertigung bevorzugt. Es scheint Benutzer zu ermutigen, APIs auf niedriger Ebene zu verwenden, ohne sie zu verstehen.
Es wird auch ein Kontext-Manager erstellt, der durch die bedingungslose Rückgabe von True
alle Ausnahmen (einschließlich KeyboardInterrupt
und SystemExit
!) Unbemerkt weitergibt. Dies ist eine gute Möglichkeit, Fehler zu verbergen.
Dies scheint die Benutzer zu ermutigen, schlechte Praktiken anzuwenden.
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!"
Durch das Importieren von os
wird das Navigieren und Ausführen von Standardaktionen mit Ihrem Betriebssystem vereinfacht.
Zum Nachschlagen siehe auch Wie prüfe ich mit Python, ob eine Datei existiert?
Wenn Sie Operationen auf hoher Ebene benötigen, verwenden Sie shutil
.
Testen von Dateien und Ordnern mit os.path.isfile()
, os.path.isdir()
und os.path.exists()
Unter der Annahme, dass der "Pfad" ein gültiger Pfad ist, zeigt diese Tabelle, was von jeder Funktion für Dateien und Ordner zurückgegeben wird:
Sie können auch testen, ob es sich bei einer Datei um einen bestimmten Dateityp handelt, indem Sie os.path.splitext()
verwenden, um die Erweiterung abzurufen (sofern Sie diese noch nicht kennen).
>>> 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
Im Jahr 2016 verwendet der beste Weg immer noch os.path.isfile
:
>>> os.path.isfile('/path/to/some/file.txt')
Oder in Python 3 können Sie pathlib
verwenden:
import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
...
Es scheint nicht so, als gäbe es einen bedeutenden funktionalen Unterschied zwischen try/except und isfile()
, daher sollten Sie verwenden, welches sinnvoll ist.
Wenn Sie eine Datei lesen möchten, tun Sie dies, falls vorhanden
try:
f = open(filepath)
except IOError:
print 'Oh dear.'
Wenn Sie eine Datei jedoch nur umbenennen möchten, wenn sie vorhanden ist, und sie daher nicht öffnen müssen, müssen Sie dies tun
if os.path.isfile(filepath):
os.rename(filepath, filepath + '.old')
Wenn Sie in eine Datei schreiben möchten, tun Sie dies, wenn sie nicht vorhanden ist
# 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'
Wenn Sie eine Dateisperrung benötigen, ist das eine andere Sache.
Sie könnten dies versuchen (sicherer):
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))
Die Ausgabe wäre:
([Errno 2] Keine solche Datei oder Verzeichnis: 'whatever.txt')
Abhängig vom Ergebnis kann Ihr Programm dann von dort aus weiterlaufen oder Sie können programmieren, um es zu stoppen, wenn Sie möchten.
Obwohl ich immer die Verwendung der Anweisungen try
und except
empfehle, gibt es hier einige Möglichkeiten für Sie (mein persönlicher Favorit ist die Verwendung von os.access
):
Versuchen Sie, die Datei zu öffnen:
Beim Öffnen der Datei wird immer überprüft, ob die Datei vorhanden ist. Sie können eine Funktion wie folgt erstellen:
def File_Existence(filepath):
f = open(filepath)
return True
Wenn es falsch ist, wird die Ausführung mit einem nicht behandelten IOError oder OSError in späteren Versionen von Python gestoppt. Um die Ausnahme abzufangen, müssen Sie eine try except-Klausel verwenden. Natürlich können Sie immer eine try
except`-Anweisung wie folgt verwenden (danke an hsandt , damit ich nachdenke):
def File_Existence(filepath):
try:
f = open(filepath)
except IOError, OSError: # Note OSError is for later versions of Python
return False
return True
Benutze os.path.exists(path)
:
Dadurch wird überprüft, ob das von Ihnen angegebene Objekt vorhanden ist. Es wird jedoch nach Dateien und Verzeichnissen gesucht. Achten Sie also darauf, wie Sie diese verwenden.
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
Benutze os.access(path, mode)
:
Dadurch wird überprüft, ob Sie Zugriff auf die Datei haben. Es wird nach Berechtigungen gesucht. Basierend auf der os.py-Dokumentation wird durch Eingabe von os.F_OK
die Existenz des Pfads überprüft. Dies führt jedoch zu einer Sicherheitslücke, da jemand Ihre Datei in der Zeit zwischen dem Überprüfen der Berechtigungen und dem Öffnen der Datei angreifen kann. Sie sollten stattdessen direkt zum Öffnen der Datei gehen, anstatt ihre Berechtigungen zu überprüfen. ( EAFP vs LBYP ). Wenn Sie die Datei anschließend nicht öffnen und nur ihre Existenz überprüfen möchten, können Sie diese verwenden.
Wie auch immer, hier:
>>> import os
>>> os.access("/is/a/file.txt", os.F_OK)
True
Ich sollte auch erwähnen, dass es zwei Möglichkeiten gibt, die Existenz einer Datei nicht zu überprüfen. Entweder ist das Problem permission denied
oder no such file or directory
. Wenn Sie einen IOError
finden, setzen Sie den IOError as e
(wie meine erste Option) und geben Sie dann print(e.args)
ein, damit Sie hoffentlich Ihr Problem bestimmen können. Ich hoffe, es hilft! :)
Datum: 2017-12-04
Jede mögliche Lösung wurde in anderen Antworten aufgeführt.
Eine intuitive und sinnvolle Methode, um zu überprüfen, ob eine Datei vorhanden ist, ist die folgende:
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')
Ich habe ein ausführliches Spickzettel erstellt:
#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']}
Zusätzlich os.access()
:
if os.access("myfile", os.R_OK):
with open("myfile") as fp:
return fp.read()
Als R_OK
, W_OK
und X_OK
die Flags zum Testen von Berechtigungen ( doc ).
Wenn die Datei zum Öffnen vorgesehen ist, können Sie eine der folgenden Techniken verwenden:
>>> 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
Um Verwirrung zu vermeiden und basierend auf den Antworten, die ich erhalten habe, findet die aktuelle Antwort entweder eine Datei oder ein Verzeichnis mit dem angegebenen Namen.
if os.path.isfile(path_to_file):
try:
open(path_to_file)
pass
except IOError as e:
print "Unable to open file"
Das Auslösen von Ausnahmen wird als akzeptabler und pythonischer Ansatz für die Ablaufsteuerung in Ihrem Programm angesehen. Erwägen Sie den Umgang mit fehlenden Dateien mit IOErrors. In dieser Situation wird eine IOError-Ausnahme ausgelöst, wenn die Datei vorhanden ist, der Benutzer jedoch keine Leseberechtigungen hat.
Wenn Sie NumPy bereits für andere Zwecke importiert haben, müssen keine weiteren Bibliotheken wie pathlib
, os
, paths
usw. importiert werden.
import numpy as np
np.DataSource().exists("path/to/your/file")
Dies wird basierend auf seiner Existenz wahr oder falsch zurückgeben.
Sie können Brians Vorschlag ohne den try:
schreiben.
from contextlib import suppress
with suppress(IOError), open('filename'):
process()
suppress
ist Teil von Python 3.4. In älteren Releases können Sie schnell Ihre eigene Unterdrückung schreiben:
from contextlib import contextmanager
@contextmanager
def suppress(*exceptions):
try:
yield
except exceptions:
pass
Sie können diesen drei Möglichkeiten folgen:
Hinweis 1: Der
os.path.isfile
wird nur für Dateien verwendet
import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists
Hinweis 2: Der
os.path.exists
, der sowohl für Dateien als auch für Verzeichnisse verwendet wird
import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists
Die
pathlib.Path
-Methode (enthalten in Python 3+, installierbar mit pip für Python 2)
from pathlib import Path
Path(filename).exists()
Hinzufügen einer weiteren geringfügigen Variation, die sich nicht genau in den anderen Antworten widerspiegelt.
Dies behandelt den Fall, dass file_path
None
oder eine leere Zeichenfolge ist.
def file_exists(file_path):
if not file_path:
return False
Elif not os.path.isfile(file_path):
return False
else:
return True
Hinzufügen einer Variante auf Vorschlag von Shahbaz
def file_exists(file_path):
if not file_path:
return False
else:
return os.path.isfile(file_path)
Hinzufügen einer Variante auf Vorschlag von Peter Wood
def file_exists(file_path):
return file_path and os.path.isfile(file_path):
Ich bin der Autor eines Pakets, das es seit ungefähr 10 Jahren gibt, und es hat eine Funktion, die diese Frage direkt anspricht. Wenn Sie sich auf einem Nicht-Windows-System befinden, wird Popen
verwendet, um auf find
zuzugreifen. Wenn Sie jedoch unter Windows arbeiten, wird find
mit einem effizienten Dateisystem-Walker repliziert.
Der Code selbst verwendet keinen try
-Block ... außer zur Bestimmung des Betriebssystems und damit zur Steuerung des "Unix" -Stils find
oder des von Hand erstellten find
. Timing-Tests haben gezeigt, dass try
das Betriebssystem schneller bestimmt, also habe ich dort eins verwendet (aber nirgendwo anders).
>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']
Und der 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']
>>>
Die Implementierung finden Sie hier: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L19
Hier ist ein 1-zeiliger Befehl Python für die Linux-Befehlszeilenumgebung. Ich finde das SEHR HANDY, da ich kein so heißer Bash-Typ bin.
python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"
Ich hoffe das ist hilfreich.
Wie überprüfe ich, ob eine Datei vorhanden ist, ohne die try-Anweisung zu verwenden?
Im Jahr 2016 ist dies immer noch der einfachste Weg, um zu überprüfen, ob eine Datei existiert und ob es sich um eine Datei handelt:
import os
os.path.isfile('./file.txt') # Returns True if exists, else False
isfile
ist eigentlich nur eine Hilfsmethode, die intern os.stat
und stat.S_ISREG(mode)
darunter verwendet. Bei diesem os.stat
handelt es sich um eine untergeordnete Methode, mit der Sie detaillierte Informationen zu Dateien, Verzeichnissen, Sockets, Puffern und vielem mehr erhalten. Mehr über os.stat hier
Hinweis: Bei diesem Ansatz wird die Datei jedoch in keiner Weise gesperrt, sodass Ihr Code anfällig für " Zeitpunkt der Überprüfung bis zum Zeitpunkt der Verwendung "(TOCTTOU) Fehler.
Das Auslösen von Ausnahmen wird daher als akzeptabler und pythonischer Ansatz für die Ablaufsteuerung in Ihrem Programm angesehen. Und man sollte erwägen, fehlende Dateien mit IOErrors zu behandeln, anstatt if
Anweisungen ( nur einen Ratschlag ).
Sie können die "OS" -Bibliothek von Python verwenden:
>>> 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)
Mit der folgenden Methode können Sie überprüfen, ob eine Datei vorhanden und lesbar ist:
open(inputFile, 'r')
import os
path = /path/to/dir
root,dirs,files = os.walk(path).next()
if myfile in files:
print "yes it exists"
Dies ist hilfreich, wenn Sie nach mehreren Dateien suchen. Oder Sie möchten eine Schnittmenge/Subtraktion mit einer vorhandenen Liste festlegen.
So überprüfen Sie, ob eine Datei vorhanden ist:
from sys import argv
from os.path import exists
script, filename = argv
target = open(filename)
print "file exists: %r" % exists(filename)
Mit os.listdir können Sie überprüfen, ob sich eine Datei in einem bestimmten Verzeichnis befindet.
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))
Grundsätzlich eine Ordnerprüfung, dann eine Dateiprüfung mit dem richtigen Verzeichnis-Trennzeichen unter Verwendung von os.path.join.
Sie sollten auf jeden Fall dieses verwenden.
from os.path import exists
if exists("file") == True:
print "File exists."
Elif exists("file") == False:
print "File doesn't exist."
Es wird wahrscheinlich nicht benötigt, aber wenn ja, hier ist ein 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