it-swarm-eu.dev

Wie überprüfe ich, ob eine Datei ohne Ausnahmen existiert?

Wie kann ich feststellen, ob eine Datei vorhanden ist oder nicht, ohne die Anweisung try zu verwenden?

5178
spence91

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
_
4764
rslite

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.

1971
PierreBdR

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
911
bortzmeyer
import os.path

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

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"
276
Yugal Jindle
import os
os.path.exists(path) # Returns whether the path (directory or file) exists or not
os.path.isfile(path) # Returns whether the file exists or not
265
benefactual

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:

  1. Datei prüfen (arguable: auch Ordner ("spezielle" Datei)?)
  2. Verwenden Sie nicht try_/except_/else_/finally Blöcke

Mögliche Lösungen:

  1. [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. Gibt False für unterbrochene symbolische Links zurück. Auf einigen Plattformen gibt diese Funktion möglicherweise False 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 ()

    • Es ist eine schickere (und mehr python ic) Art, mit Pfaden umzugehen, aber
    • 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
      
  2. [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.

  3. Funktionen zum Durchsuchen des Dateisystems (und Durchsuchen der Ergebnisse nach übereinstimmenden Elementen)


    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.

  4. [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)

    • Benutzerberechtigungen kann die "Sichtbarkeit" der Datei einschränken, wie im Dokument angegeben:

      ... 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:

    • Es ist zwar keine gute Vorgehensweise, ich verwende os.F_OK Im Aufruf, aber dies dient nur der Klarheit (sein Wert ist )
    • Ich verwende _waccess, damit derselbe Code auf Python und Python2 funktioniert (trotz der Unterschiede zwischen nicode).
    • Obwohl dies auf einen ganz bestimmten Bereich abzielt, wurde in keiner der vorherigen Antworten erwähnt


    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.

      • Das (aktuelle) Hauptprogramm (python) ist mit libc verknüpft, daher werden seine Symbole (einschließlich access) geladen
      • Dies muss mit Vorsicht behandelt werden, da Funktionen wie main, Py_Main und (alle) andere verfügbar sind. Anruf könnte katastrophale Auswirkungen haben (auf das aktuelle Programm)
      • Dies gilt auch nicht für Win (aber das ist keine große Sache, da msvcrt.dll in "% SystemRoot%\System32" gespeichert ist, das sich in % PATH befindet % standardmäßig). Ich wollte die Dinge weiterentwickeln und dieses Verhalten auf Win replizieren (und einen Patch einreichen), aber wie sich herausstellt, [MS.Docs]: GetProcAddress-Funktion nur "sieht" exportiert Symbole, es sei denn, jemand deklariert die Funktionen in der ausführbaren Hauptdatei als __declspec(dllexport) (warum um alles in der Welt würde die regular Person das tun?), das Hauptprogramm ist ladbar aber ziemlich unbrauchbar
  5. Installieren 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.

  6. 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:

  • Do use try_/except_/else_/finally blockiert, weil sie verhindern können, dass Sie auf eine Reihe böser Probleme stoßen. Ein Gegenbeispiel, das ich mir vorstellen kann, ist die Leistung: Solche Blöcke sind kostspielig. Versuchen Sie daher, sie nicht in Code zu platzieren, der Hunderttausende Male pro Sekunde ausgeführt werden soll. es wird nicht der Fall sein).

Schlussnote (n):

  • Ich werde versuchen, es auf dem neuesten Stand zu halten, alle Vorschläge sind willkommen, ich werde alles Nützliche einbeziehen, das in die Antwort einfließt
222
CristiFati

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")
149
un33k

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
136
Cody Piersall

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:

120
pkoch

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.

Längere, umständlichere Antwort

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
_

Rennbedingungen: Warum wir es gerne probieren

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 .

Vermeiden von Rennbedingungen ohne eine Versuchsanweisung: 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
_

Andere Optionen, die die Frage nach "ohne zu versuchen" nicht erfüllen:

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 auch isfile() 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.

Kritik an einer anderen Antwort:

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.

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

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.

84
喬治扎菲

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:

enter image description here

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
79
Tom Fuller

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():
    ...
68
KaiBuxe

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.

63
chad

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.

56
philberndt

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):

  1. 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
    
  2. 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
    
  3. 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! :)

50
Zizouz212

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']}
44
Algebra

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 ).

35
zgoda

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.

32
bergercookie
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.

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

21
Pedro Lobito

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.

18
durjoy

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
17
Chris

Überprüfen Sie, ob eine Datei oder ein Verzeichnis vorhanden ist

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()
16
Ali Hallaji

Hinzufügen einer weiteren geringfügigen Variation, die sich nicht genau in den anderen Antworten widerspiegelt.

Dies behandelt den Fall, dass file_pathNone 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):
15
Marcel Wilson

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

15
Mike McKerns

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 ).

11
Inconnu

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
11
Pradip Das
import os.path

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

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

isReadableFile(path, fileName)
9
Khaled.K

Mit der folgenden Methode können Sie überprüfen, ob eine Datei vorhanden und lesbar ist:

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

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

Dies ist hilfreich, wenn Sie nach mehreren Dateien suchen. Oder Sie möchten eine Schnittmenge/Subtraktion mit einer vorhandenen Liste festlegen.

8
Jesvin Jose

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)
6
Hanson

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
4
iPhynx
import os

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

Grundsätzlich eine Ordnerprüfung, dann eine Dateiprüfung mit dem richtigen Verzeichnis-Trennzeichen unter Verwendung von os.path.join.

3

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."
2
user2154354

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