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

Antworten:

5153

Wenn der Grund, den Sie überprüfen, darin besteht, dass Sie so etwas tun können if file_exists: open_it(), ist es sicherer, ein tryum den Versuch herum zu verwenden, es zu öffnen. Beim Überprüfen und anschließenden Öffnen besteht die Gefahr, dass die Datei gelöscht oder verschoben wird oder zwischen dem Überprüfen und dem Versuch, sie zu öffnen.

Wenn Sie nicht vorhaben, die Datei sofort zu öffnen, können Sie sie verwenden os.path.isfile

Rückgabe, Truewenn der Pfad eine vorhandene reguläre Datei ist. Dies folgt symbolischen Verknüpfungen, sodass sowohl islink () als auch isfile () für denselben Pfad wahr sein 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 pathlibModul einen objektorientierten Ansatz (auf pathlib2Python 2.7 zurückportiert):

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

PathVerwenden Sie Folgendes, um zu überprüfen, ob ein Objekt unabhängig davon existiert, ob es sich um eine Datei oder ein Verzeichnis handelt exists():

if my_file.exists():
    # path exists

Sie können auch resolve(strict=True)in einem tryBlock verwenden:

try:
    my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
    # doesn't exist
else:
    # exists
rslite
quelle
40
In Bezug auf die erste Bemerkung (verwenden Sie "try", wenn vor dem Öffnen geprüft) funktioniert dies leider nicht, wenn Sie zum Anhängen öffnen möchten, um sicherzugehen, dass es vorher existiert, da der 'a'-Modus erstellt wird, wenn er nicht existiert.
Makapuf
6
Beachten Sie, dass dies FileNotFoundErrorin Python 3 eingeführt wurde. Wenn Sie neben Python 3 auch Python 2.7 unterstützen müssen, können Sie IOErrorstattdessen (welche FileNotFoundErrorUnterklassen) stackoverflow.com/a/21368457/1960959
scottclowe
7
@makapuf Sie können es zum "Aktualisieren" ( open('file', 'r+')) öffnen und dann bis zum Ende suchen.
Kirill
2111

Sie haben die os.path.existsFunktion:

import os.path
os.path.exists(file_path)

Dies gibt Truesowohl für Dateien als auch für Verzeichnisse zurück, aber Sie können stattdessen verwenden

os.path.isfile(file_path)

um zu testen, ob es sich speziell um eine Datei handelt. Es folgen Symlinks.

PierreBdR
quelle
965

Im Gegensatz zu isfile(), exists()kehrt Truefür Verzeichnisse. Je nachdem, ob Sie nur einfache Dateien oder auch Verzeichnisse möchten, verwenden Sie isfile()oder exists(). Hier ist eine einfache REPL-Ausgabe:

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

if os.path.isfile(filepath):
Paul
quelle
320

Verwendung os.path.isfile()mit 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")
Yugal Jindle
quelle
60
Es ist weniger klar und explizit , mehrere Bedingungen zu haben, von denen einige überflüssig sind .
wim
10
Es ist auch redundant. Wenn die Datei nicht vorhanden ist, os.access()wird false zurückgegeben.
user207421
9
@EJP Unter Linux können Dateien vorhanden sein, die jedoch nicht zugänglich sind.
E-Info128
8
da du import os, musst du nicht import os.pathnochmal da es schon ein teil von ist os. Sie müssen nur importieren, os.pathwenn Sie nur Funktionen von os.pathund nicht von sich osselbst verwenden möchten, um eine kleinere Sache zu importieren. Wenn Sie jedoch os.accessund verwenden os.R_OK, wird der zweite Import nicht benötigt.
Jester
287
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
wohltätig
quelle
2
Im Allgemeinen empfiehlt es sich nicht, Variablen mit Methodennamen zu benennen.
Homunculus Reticulli
245

Obwohl fast jeder mögliche Weg in (mindestens einer) der vorhandenen Antworten aufgeführt wurde (z. B. wurde Python 3.4- spezifisches Material hinzugefügt), werde ich versuchen, alles zusammenzufassen.

Hinweis : Jeder Teil des Python- Standardbibliothekscodes, den ich veröffentlichen werde, gehört zur Version 3.5.3 .

Problemstellung :

  1. Datei überprüfen ( fraglich Existenz der : auch Ordner ("spezielle" Datei)?)
  2. Verwenden Sie keine Try / außer / else / finally- Blöcke

Mögliche Lösungen :

  1. [Python 3]: os.path. existiert ( Pfad ) (auch andere Funktion Familienmitglieder überprüfen , wie os.path.isfile, os.path.isdir, os.path.lexistsfür etwas andere Verhaltensweisen)

    os.path.exists(path)

    Rückgabe, Truewenn sich der Pfad auf einen vorhandenen Pfad oder einen offenen Dateideskriptor bezieht. Gibt Falsefür defekte symbolische Links zurück. Auf einigen Plattformen kann diese Funktion zurückgegeben werden, Falsewenn keine Berechtigung zum Ausführen von os.stat () für die angeforderte Datei erteilt wurde , selbst wenn der Pfad physisch vorhanden ist.

    Alles gut, 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 ( Pfad, *, dir_fd = Keine, follow_symlinks = True ) . Ihr Code ist also try / außer free, aber tiefer im Framestack befindet sich (mindestens) ein solcher Block. Dies gilt auch für andere Funktionen ( einschließlich os.path.isfile ).

    1.1. [Python 3]: Pfad. is_file ()

    • Es ist ein schicker (und Python ic) Art und Weise Wege der Handhabung, aber
    • Unter der Haube macht es genau das Gleiche ( pathlib.py , Zeile ~ # 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
  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 os.path.isfileVerhalten replizieren (beachten Sie, dass dies nur zu Demonstrationszwecken dient, versuchen Sie nicht , solchen Code für die Produktion 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. unterdrücken ( * Ausnahmen ) - wurde speziell zum selektiven Unterdrücken von Ausnahmen entwickelt


    Aber sie scheinen Wrapper über try / exception / else / finally- Blöcke zu sein, wie in [Python 3] angegeben: Die with- Anweisung besagt:

    Auf diese Weise können allgemeine Versuche ... außer ... schließlich Verwendungsmuster für eine bequeme Wiederverwendung gekapselt werden.

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


    Da diese Iterierte über Ordner (in den meisten Fällen) sie für unser Problem ineffizient sind (es gibt Ausnahmen, wie nicht wildcarded glob bing - wie @ShadowRanger wies darauf hin), so bin ich nicht auf sie los zu bestehen. Ganz zu schweigen davon, dass in einigen Fällen eine Dateinamenverarbeitung erforderlich sein kann.

  4. [Python 3]: os. Zugang ( Pfad, Modus, *, dir_fd = None, effective_ids = False, follow_symlinks = True ) , dessen Verhalten in der Nähe os.path.exists(eigentlich ist es weiter, vor allem wegen des 2 nd Arguments)

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

      ... testen, ob der aufrufende Benutzer den angegebenen Zugriff auf den Pfad hat . Modus sollte F_OK sein , um die Existenz eines Pfades zu testen ...

    os.access("/tmp", os.F_OK)

    Da ich in auch Arbeit C , verwende ich diese Methode als auch , weil unter der Haube, ruft es nativen API s (wieder über „$ {} PYTHON_SRC_DIR /Modules/posixmodule.c“ ), aber es eröffnet auch ein Tor für mögliche Benutzer Fehler , und es ist nicht so Python ic wie andere Varianten. Verwenden Sie es also, wie @AaronHall zu Recht betont hat, nur, wenn Sie wissen, was Sie tun:

    Hinweis : Das Aufrufen nativer APIs ist auch über [Python 3] möglich: ctypes - Eine Fremdfunktionsbibliothek für Python , in den meisten Fällen jedoch komplizierter.

    ( Win- spezifisch): Da vcruntime * ( msvcr * ) .dll eine [MS.Docs] exportiert : _access, _waccess- Funktionsfamilie ebenfalls, 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 :

    • Obwohl es keine gute Praxis ist, verwende ich sie os.F_OKim Aufruf, aber das dient nur der Klarheit (der Wert ist 0 ).
    • Ich verwende _waccess, damit der gleiche Code auf Python3 und Python2 funktioniert (trotz Unicode bezogenen Unterschieden zwischen ihnen).
    • Obwohl dies auf einen ganz bestimmten Bereich abzielt, wurde es in keiner der vorherigen Antworten erwähnt


    Das Gegenstück zu Lnx ( Ubtu (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 :

    • Statt hartzucodieren libc ‚s Pfad ( ‚/lib/x86_64-linux-gnu/libc.so.6‘ ) , die kann (und wahrscheinlich wird) über Systeme variieren, keine (oder die leere Zeichenkette) kann übergeben werden CDLL Konstruktor ( ctypes.CDLL(None).access(b"/tmp", os.F_OK)). Nach [man7]: DLOPEN (3) :

      Wenn der Dateiname 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 gemeinsam genutzten Objekten, die beim Programmstart geladen wurden, und allen gemeinsam genutzten Objekten, die von dlopen () mit dem Flag RTLD_GLOBAL geladen wurden .

      • Das Hauptprogramm ( Python ) ist mit libc verknüpft , sodass seine Symbole (einschließlich Zugriff ) geladen werden
      • Dies muss mit Vorsicht behandelt werden, da Funktionen wie main , Py_Main und (alle) anderen verfügbar sind. Ein Anruf könnte katastrophale Auswirkungen haben (auf das aktuelle Programm).
      • Dies gilt nicht auch für Win (aber das ist keine große Sache, da sich msvcrt.dll in "% SystemRoot% \ System32" befindet, das standardmäßig in % PATH% steht ). Ich wollte die Dinge weiterentwickeln und dieses Verhalten unter Win replizieren (und einen Patch einreichen), aber wie sich herausstellt, "sieht" die Funktion " GetProcAddress " nur exportierte Symbole, es sei denn, jemand deklariert die Funktionen in der ausführbaren Hauptdatei as __declspec(dllexport)(warum um alles in der Welt würde die normale Person das tun?), das Hauptprogramm ist ladbar, aber ziemlich unbrauchbar
  5. Installieren Sie ein Modul eines Drittanbieters mit Dateisystemfunktionen

    Wird sich höchstwahrscheinlich auf einen der oben genannten Wege stützen (möglicherweise mit geringfügigen Anpassungen).
    Ein Beispiel wäre (wieder Win- spezifisch) [GitHub]: mhammond / pywin32 - Python für Windows (pywin32) Extensions , ein Python- Wrapper über WINAPIs .

    Aber da dies eher eine Problemumgehung ist, höre ich hier auf.

  6. Eine andere (lahme) Problemumgehung ( Gainarie ) ist (wie ich es gerne nenne) der Sysadmin- Ansatz: Verwenden Sie Python als Wrapper, um Shell-Befehle auszuführen

    • Gewinnen :

      (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

Fazit :

  • Haben Verwendung try / ausnehmen / else / schließlich blockiert, weil sie verhindern , können Sie in eine Reihe von bösen Probleme läuft. Ein Gegenbeispiel, an das ich denken kann, ist die Leistung: Solche Blöcke sind kostspielig. Versuchen Sie daher, sie nicht in Code zu platzieren, der hunderttausend Mal pro Sekunde ausgeführt werden soll (da es sich jedoch (in den meisten Fällen) um Festplattenzugriff handelt, es wird nicht der Fall sein).

Schlussbemerkung (en) :

  • Ich werde versuchen, es auf dem neuesten Stand zu halten. Vorschläge sind willkommen. Ich werde alles Nützliche in die Antwort aufnehmen
CristiFati
quelle
3
Können Sie diese Aussage näher erläutern? "Obwohl es keine gute Praxis ist, verwende ich os.F_OK im Aufruf, aber das dient nur der Klarheit (sein Wert ist 0)"
sk8asd123
6
@ sk8asd123: Es ist schwierig, dies in einem Kommentar zu tun: Im Allgemeinen ist es am besten, Konstanten mit Funktionen zu verwenden, mit denen sie zusammenkommen. Dies gilt, wenn Sie mit mehreren Modulen arbeiten, die dieselbe Konstante definieren, da einige möglicherweise nicht auf dem neuesten Stand sind und die Funktionen und Konstanten am besten synchron sind. Wenn ich mit ctypes arbeite (die Funktionen direkt aufrufe ), hätte ich die Konstante (von MSDN ) definieren oder überhaupt keine Konstante verwenden sollen. Es ist nur eine Richtlinie, die ich verwende, bei 99,9% macht es wahrscheinlich keinen Unterschied (funktional).
CristiFati
3
@CristiFati: Ab 3.6 glob.iglob(und glob.globauch) basieren aufos.scandir , also ist es jetzt faul; Um den ersten Treffer in einem Verzeichnis mit 10 Millionen Dateien zu erhalten, scannen Sie nur, bis Sie den ersten Treffer erreichen. Und selbst vor Version 3.6 ist globdie Funktion intelligent , wenn Sie Methoden ohne Platzhalter verwenden: Sie weiß, dass Sie nur einen Treffer erzielenos.path.isdiros.path.lexists können, und vereinfacht das Globbing auf nur oder (je nachdem, ob der Pfad endet /).
ShadowRanger
3
Dieser zweite Teil meines Kommentars (nicht platziertes Globbing iteriert den Ordner nicht und hat es auch nie getan) bedeutet, dass es eine perfekt effiziente Lösung für das Problem ist (langsamer als direktes Aufrufen os.path.isdiroder os.path.lexistda es sich um eine Reihe von Funktionsaufrufen und Zeichenfolgen auf Python-Ebene handelt Operationen, bevor entschieden wird, dass der effiziente Pfad realisierbar ist, aber kein zusätzlicher Systemaufruf oder E / A-Arbeit (um Größenordnungen langsamer).
ShadowRanger
154

Dies ist der einfachste Weg, um zu überprüfen, ob eine Datei vorhanden ist. Nur weil die Datei bei der Überprüfung vorhanden war, kann nicht garantiert werden, dass sie beim Öffnen vorhanden ist.

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")
un33k
quelle
17
Solange Sie auf die Datei zugreifen möchten, die Race - Bedingung vorhanden ist , unabhängig davon , wie Ihr Programm aufgebaut ist. Ihr Programm kann nicht garantieren, dass ein anderer Prozess auf dem Computer die Datei nicht geändert hat. Es ist das, was Eric Lippert als exogene Ausnahme bezeichnet . Sie können dies nicht vermeiden, indem Sie zuvor prüfen, ob die Datei vorhanden ist.
Isaac Supeene
@IsaacSupeene Best Practice ist es, das Fenster der (Datei-) Operation so klein wie möglich zu machen, gefolgt von einer ordnungsgemäßen Ausnahmebehandlung
un33k
145

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 normalerweise) try/exceptbeim Öffnen von Dateien weiterhin einen Block verwenden:

try:
    with p.open() as f:
        # do awesome stuff
except OSError:
    print('Well darn.')

Das pathlib-Modul enthält viele coole Dinge: bequemes Globbing, Überprüfen des Dateibesitzers, einfacheres Verbinden von Pfaden usw. Es lohnt sich, es sich anzusehen. Wenn Sie mit einem älteren Python (Version 2.6 oder höher) arbeiten, können Sie pathlib weiterhin mit pip installieren:

# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2

Importieren Sie es dann wie folgt:

# Older Python versions
import pathlib2 as pathlib
Cody Piersall
quelle
124

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:

pkoch
quelle
3
Bitte fügen Sie bessere Quellen hinzu, um Ihre Aussage zu unterstützen.
BlueTrin
11
Der zitierte Link Vermeiden von Rennbedingungen (Apple Dev Support) unterstützt Ihre Antwort nicht. Es geht nur darum, temporäre Dateien zu verwenden, die vertrauliche Informationen auf schlecht gestalteten Betriebssystemen enthalten, die temporäre Dateien / Verzeichnisse mit eingeschränkten Berechtigungen nicht ordnungsgemäß sandboxen. Die Verwendung try...excepthilft ohnehin nicht, dieses Problem zu lösen .
jstine
Das Problem bei dieser Methode besteht darin, dass, wenn Sie einen wichtigen Code abhängig von der nicht vorhandenen Datei haben, das Einfügen in die except:Klausel dazu führt, dass eine in diesem Teil Ihres Codes auftretende Ausnahme eine verwirrende Meldung auslöst (zweiter Fehler während die Verarbeitung des ersten.)
Camion
119

Wie überprüfe ich mithilfe von Python, ob eine Datei vorhanden ist, ohne eine try-Anweisung zu verwenden?

Jetzt seit Python 3.4 verfügbar, importieren und instanziieren Sie ein PathObjekt mit dem Dateinamen und überprüfen Sie die is_fileMethode (beachten Sie, dass dies True für Symlinks zurückgibt, die auch 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 aus zurückportieren pathlib2oder auf andere Weise isfilevom Modul aus überprüfen os.path:

>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False

Das Obige ist hier wahrscheinlich die beste pragmatische direkte Antwort, aber es besteht die Möglichkeit einer Race-Bedingung (abhängig davon, was Sie erreichen möchten) und die Tatsache, dass die zugrunde liegende Implementierung a verwendet try, Python jedoch verwendettry überall in ihrer Implementierung verwendet.

Weil Python verwendet try überall verwendet wird, 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, viel pedantischere Antwort

Verwenden Sie das neue PathObjekt in Python 3.4 pathlib. Beachten Sie, dass dies .existsnicht 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 verwenden is_file:

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

Holen wir uns also eine Datei, 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 wird NamedTemporaryFiledie Datei beim Schließen gelöscht (und automatisch geschlossen, wenn keine weiteren Verweise darauf vorhanden sind).

>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False

Wenn Sie sich vertiefen der Implementierung befassen, werden Sie feststellen, dass is_fileFolgendes verwendet wird 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

Rennbedingungen: Warum wir es gerne versuchen

Wir mögen, tryweil es Rennbedingungen vermeidet. Mit tryversuchen Sie einfach, Ihre Datei zu lesen, und erwarten, dass sie dort vorhanden ist. Wenn nicht, fangen Sie die Ausnahme ab und führen das Fallback-Verhalten aus, das sinnvoll ist.

Wenn Sie überprüfen möchten, ob eine Datei vorhanden ist, bevor Sie versuchen, sie zu lesen, und Sie sie möglicherweise löschen und dann möglicherweise mehrere Threads oder Prozesse verwenden oder ein anderes Programm diese Datei kennt und sie löschen könnte, besteht die Gefahr, dass dies der Fall ist eine Rennbedingung wenn Sie überprüfen, ob sie vorhanden ist, weil Sie dann versuchen , sie vor ihrer Bedingung zu öffnen (ihre Existenz) ändert.

Die Rennbedingungen sind sehr schwer zu debuggen, da es ein sehr kleines Fenster gibt, in dem Ihr Programm fehlschlagen kann.

Aber wenn dies Ihre Motivation, Sie können Sie den Wert einer tryAussage mithilfe von ermittelnsuppress Kontextmanagers ermitteln.

Vermeiden Sie Rennbedingungen ohne eine Try-Anweisung: suppress

Python 3.4 gibt uns den suppressKontextmanager (früher der ignoreKontextmanager), der in weniger Zeilen semantisch genau dasselbe tut und gleichzeitig (zumindest oberflächlich) die ursprüngliche Aufforderung erfüllt, eine tryAussage 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 würfeln suppress, aber ohne a trywird es ausführlicher als mit. Ich glaube, dies ist tatsächlich die einzige Antwort, die tryauf keiner Ebene in Python verwendet wird und auf die vor Python 3.4 angewendet werden kann, 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 Versuch" nicht erfüllen:

isfile

import os
os.path.isfile(path)

aus den Dokumenten :

os.path.isfile(path)

Geben Sie True zurück, wenn der Pfad eine vorhandene reguläre Datei ist. Dies folgt symbolischen Verknüpfungen, also beides islink()und isfile()kann für denselben Pfad zutreffen.

Wenn Sie jedoch die Quelle 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 sehen, ob Statistiken darauf abgerufen werden können, abzufangen OSErrorund dann zu überprü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, es direkt mit einem Versuch zu versuchen - außer um eine Rennbedingung 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 um zu verwenden, 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 Zugriff in einer Umgebung mit erhöhten Berechtigungen hat:

import os
os.access(path, os.F_OK)

Es leidet auch unter den gleichen Problemen mit den Rennbedingungen wie isfile. Aus den Dokumenten :

Hinweis: Wenn Sie mit access () prüfen, ob ein Benutzer berechtigt ist, z. B. eine Datei zu öffnen, bevor Sie dies tatsächlich mit open () tun, entsteht eine Sicherheitslücke, da der Benutzer möglicherweise das kurze Zeitintervall zwischen dem Überprüfen und Öffnen der Datei ausnutzt, um sie zu bearbeiten. 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()

Vermeide das Benutzen os.access . Es handelt sich um 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 eine nicht pythonische, fehleranfällige Methode ohne Rechtfertigung bevorzugt wird. Es scheint Benutzer zu ermutigen, APIs auf niedriger Ebene zu verwenden, ohne sie zu verstehen.

Außerdem wird ein Kontextmanager erstellt, der durch bedingungslose Rückgabe Truealle Ausnahmen (einschließlich KeyboardInterruptund SystemExit!) Im Stillen passieren lässt. Dies ist eine gute Möglichkeit, Fehler zu verbergen.

Dies scheint die Benutzer zu ermutigen, schlechte Praktiken anzuwenden.

Aaron Hall
quelle
87
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!"

Das Importieren oserleichtert das Navigieren und Ausführen von Standardaktionen mit Ihrem Betriebssystem.

Als Referenz siehe auch Überprüfen, ob eine Datei mit Python vorhanden ist.

Wenn Sie Operationen auf hoher Ebene benötigen, verwenden Sie shutil.

Atlas
quelle
9
Diese Antwort ist falsch. os.path.existsGibt true für Dinge zurück, die keine Dateien sind, z. B. Verzeichnisse. Dies ergibt falsch positive Ergebnisse. Siehe die anderen Antworten, die empfehlen os.path.isfile.
Chris Johnson
84

Testen auf Dateien und Ordner mit os.path.isfile(), os.path.isdir()undos.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:

Geben Sie hier die Bildbeschreibung ein

Sie können auch testen, ob eine Datei ein bestimmter Dateityp ist os.path.splitext(), um die Erweiterung zu erhalten (falls Sie sie 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
Tom Fuller
quelle
72

Im Jahr 2016 ist der beste Weg immer noch os.path.isfile:

>>> os.path.isfile('/path/to/some/file.txt')

Oder in Python 3 können Sie Folgendes verwenden pathlib:

import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
    ...
KaiBuxe
quelle
3
Darf ich fragen: Was ist der Vorteil der Verwendung des Moduls 'pathlib' anstelle des Moduls 'os' in Python3 für diese Überprüfung?
Joko
3
pathlibist die OOP-Lösung von Python für Pfade. Sie können viel mehr damit machen. Wenn Sie nur die Existenz überprüfen müssen, ist der Vorteil nicht so groß.
KaiBuxe
65

Es scheint nicht so, als gäbe es einen bedeutenden funktionalen Unterschied zwischen try / without und isfile(), also sollten Sie verwenden, welches sinnvoll ist.

Wenn Sie eine Datei lesen möchten, falls vorhanden, tun Sie dies

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, tun Sie dies

if os.path.isfile(filepath):
    os.rename(filepath, filepath + '.old')

Wenn Sie in eine Datei schreiben möchten, falls diese nicht vorhanden ist, tun Sie dies

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

Tschad
quelle
3
Diese Antwort ist falsch. os.path.existsGibt true für Dinge zurück, die keine Dateien sind, z. B. Verzeichnisse. Dies ergibt falsch positive Ergebnisse. Siehe die anderen Antworten, die empfehlen os.path.isfile.
Chris Johnson
6
In Ihrem dritten Beispiel erstelle ich einen Link filepathmit dem richtigen Timing, und BAM überschreibt die Zieldatei. Sie sollten dies open(filepath, 'wx')in einem try...exceptBlock tun , um das Problem zu vermeiden.
Spektren
1
In Ihrem zweiten Beispiel erhalten Sie zumindest unter Windows eine Meldung, OSErrorfalls filepath + '.old'bereits vorhanden: "Unter Windows wird, wenn dst bereits vorhanden ist, OSError ausgelöst, auch wenn es sich um eine Datei handelt. Es gibt möglicherweise keine Möglichkeit, eine atomare Umbenennung bei dst zu implementieren benennt eine vorhandene Datei. "
Tom Myddeltyn
@TomMyddeltyn: Ab Python 3.3 wird dieos.replace Zieldatei portabel stumm ersetzt (identisch mit os.renamedem Linux-Verhalten) (es treten nur Fehler auf, wenn der Zielname vorhanden ist und ein Verzeichnis ist). Sie stecken also auf 2.x fest, aber Py3-Benutzer haben seit einigen Jahren eine gute Option.
ShadowRanger
Am renameBeispiel: Es sollte immer noch mit try/ gemacht werden except. os.rename(oder os.replaceauf modernem Python) ist atomar; Wenn Sie es überprüfen und dann umbenennen, werden unnötige Rennen und zusätzliche Systemaufrufe ausgeführt. Tun try: os.replace(filepath, filepath + '.old') except OSError: pass
Sie es
59

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 kein solches Verzeichnis: 'Whatever.txt')

Abhängig vom Ergebnis kann Ihr Programm dann einfach von dort aus weiter ausgeführt werden, oder Sie können Code verwenden, um es zu stoppen, wenn Sie möchten.

philberndt
quelle
18
Die ursprüngliche Frage fragte nach einer Lösung, die nicht verwendettry
rrs
5
Diese Antwort verfehlt den Punkt des OP. Das Überprüfen, ob eine Datei vorhanden ist, entspricht nicht dem Überprüfen, ob Sie sie öffnen können. Es wird Fälle geben, in denen eine Datei vorhanden ist, Sie sie jedoch aus verschiedenen Gründen nicht öffnen können.
Chris Johnson
51

Obwohl ich immer die Verwendung von tryund exceptAussagen empfehle , sind hier einige Möglichkeiten für Sie (mein persönlicher Favorit ist die Verwendung os.access):

  1. Versuchen Sie, die Datei zu öffnen:

    Durch das Öffnen der Datei wird immer die Existenz der Datei überprüft. 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 übergebenen 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 tryAusnahme-Anweisung wie diese verwenden (danke an hsandt , der mich zum Nachdenken gebracht hat):

    def File_Existence(filepath):
        try:
            f = open(filepath)
        except IOError, OSError: # Note OSError is for later versions of Python
            return False
    
        return True
  2. Verwendung os.path.exists(path):

    Dadurch wird die Existenz Ihrer Angaben überprüft. Es wird jedoch nach Dateien und Verzeichnissen gesucht. Achten Sie daher darauf, wie Sie es 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. Verwendung os.access(path, mode):

    Dadurch wird geprüft, ob Sie Zugriff auf die Datei haben. Es wird nach Berechtigungen gesucht. Basierend auf der os.py-Dokumentation wird beim Eingeben os.F_OKdie Existenz des Pfads überprüft. Wenn Sie dies verwenden, entsteht jedoch eine 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 deren Berechtigungen zu überprüfen. ( EAFP gegen 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, wie Sie die Existenz einer Datei nicht überprüfen können. Entweder wird das Problem sein permission deniedoder no such file or directory. Wenn Sie eine fangen IOError, setzen Sie die IOError as e(wie meine erste Option) und geben Sie sie ein , print(e.args)damit Sie hoffentlich Ihr Problem feststellen können. Ich hoffe, es hilft! :) :)

Zizouz212
quelle
51

Datum: 2017-12-04

Jede mögliche Lösung wurde in anderen Antworten aufgeführt.

Eine intuitive und streitbare Möglichkeit, 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 Cheatsheet als Referenz 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']}
Infinitesimalrechnung
quelle
37

Wenn die Datei geöffnet werden soll, 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!')

AKTUALISIEREN

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.

bergercookie
quelle
9
Diese Antwort ist falsch. os.path.existsGibt true für Dinge zurück, die keine Dateien sind, z. B. Verzeichnisse. Dies ergibt falsch positive Ergebnisse. Siehe die anderen Antworten, die empfehlen os.path.isfile.
Chris Johnson
habe auch das falsch positive Problem.
Zorglub29
docs.python.org/3/library/os.path.html#os.path.exists Zur obigen Anweisung von chris >> os.path.exists (path)> True zurückgeben, wenn path auf einen vorhandenen Pfad oder einen offenen Pfad verweist Dateideskriptor. Gibt False für fehlerhafte 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, selbst wenn der Pfad physisch vorhanden ist. In Version 3.3 geändert: Pfad kann jetzt eine Ganzzahl sein: True wird zurückgegeben, wenn es sich um einen offenen Dateideskriptor handelt, andernfalls False. In Version 3.6 geändert: Akzeptiert ein pfadähnliches Objekt.
JayRizzo
36

Zusätzlich os.access():

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()

Sein R_OK, W_OKund X_OKdie Flags zum Testen auf Berechtigungen ( doc ).

zgoda
quelle
20
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 Flusskontrolle in Ihrem Programm angesehen. Ziehen Sie in Betracht, fehlende Dateien mit IOErrors zu behandeln. 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

CONvid19
quelle
3
Das OP fragte, wie überprüft werden soll, ob eine Datei vorhanden ist. Es ist möglich, dass eine Datei vorhanden ist, Sie sie jedoch nicht öffnen können. Daher ist die Verwendung des Öffnens einer Datei als Proxy zur Überprüfung, ob die Datei vorhanden ist, nicht korrekt: Es werden falsche Negative angezeigt.
Chris Johnson
19

Wenn Sie NumPy bereits für andere Zwecke importiert dann gibt es keine Notwendigkeit, andere Bibliotheken zu importieren wie pathlib, os, pathsusw.

import numpy as np
np.DataSource().exists("path/to/your/file")

Dies wird basierend auf seiner Existenz wahr oder falsch zurückgeben.

durjoy
quelle
18

Sie können Brians Vorschlag ohne die schreiben try:.

from contextlib import suppress

with suppress(IOError), open('filename'):
    process()

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

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 Popender Zugriff verwendet find. Wenn Sie jedoch unter Windows arbeiten, wird es repliziertfind mit einem effizienten Dateisystem-Walker .

Der Code selbst verwendet keinen tryBlock… außer um das Betriebssystem zu bestimmen und Sie so zum "Unix" -Stil findoder zum Hand-Buillt zu führen find. Timing-Tests zeigten, dass das tryBetriebssystem schneller ermittelt werden konnte, daher habe ich dort eines 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#L190

Mike McKerns
quelle
17

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

Sie können diesen drei Möglichkeiten folgen:

Hinweis 1: Wird os.path.isfilenur 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: Wird os.path.existssowohl für Dateien als auch für Verzeichnisse verwendet

import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists

Die pathlib.PathMethode (in Python 3+ enthalten, mit pip für Python 2 installierbar)

from pathlib import Path
Path(filename).exists()
Ali Hallaji
quelle
16

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

Dies behandelt den Fall des file_pathSeins Noneoder der leeren Zeichenfolge.

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):
Marcel Wilson
quelle
3
if (x) return true; else return false;ist wirklich gerecht return x. Ihre letzten vier Zeilen können werden return os.path.isfile(file_path). Während wir gerade dabei sind, kann die gesamte Funktion als vereinfacht werden return file_path and os.path.isfile(file_path).
Shahbaz
Sie müssen return xim Fall von vorsichtig sein if (x). Python betrachtet eine leere Zeichenfolge als falsch. In diesem Fall würden wir eine leere Zeichenfolge anstelle eines Bools zurückgeben. Der Zweck dieser Funktion ist es, immer bool zurückzugeben.
Marcel Wilson
1
Wahr. In diesem Fall xist os.path.isfile(..)es jedoch so, dass es schon bool ist.
Shahbaz
os.path.isfile(None)löst eine Ausnahme aus, weshalb ich den if-Check hinzugefügt habe. Ich könnte es wahrscheinlich einfach in einen Versuch einwickeln / außer stattdessen, aber ich fand, dass es auf diese Weise expliziter war.
Marcel Wilson
3
return file_path and os.path.isfile(file_path)
Peter Wood
15

Hier ist ein 1-zeiliger Python-Befehl 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.

Liebe und Frieden - Joe Codeswell
quelle
6
Einzeiliger Check-in-Bash: [ -f "${file}" ] && echo "file found" || echo "file not found"(entspricht if [ ... ]; then ...; else ...; fi).
Flotzilla
12

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
Pradip Das
quelle
5
Diese Antwort ist falsch. os.path.existsGibt true für Dinge zurück, die keine Dateien sind, z. B. Verzeichnisse. Dies ergibt falsch positive Ergebnisse. Siehe die anderen Antworten, die empfehlen os.path.isfile.
Chris Johnson
Die Funktion @Chris Johnson, os.path.exists () prüft, ob im System ein Pfad vorhanden ist. PATH kann ein VERZEICHNIS oder eine DATEI sein. In beiden Fällen funktioniert es einwandfrei. Bitte versuchen Sie es mit einem Beispiel
Pradip Das
Diese Antwort funktioniert also. Großartig. Wenn der Pfad nicht der einer Datei ist. Ging es darum? Nein
Debosmit Ray
Es hängt davon ab, ob. Wenn das Ziel der Feststellung der Existenz einer "Datei" darin besteht, herauszufinden, ob der Pfad bereits vorhanden ist (und daher kein Pfad ist, in dem neue Daten gespeichert werden können, ohne andere Informationen zu löschen), existsist dies in Ordnung. Wenn das Ziel darin besteht, festzustellen, ob es sicher ist, eine vermutlich vorhandene Datei zu öffnen, ist die Kritik berechtigt und nicht präzise genug. Leider gibt das OP nicht an, welches das gewünschte Ziel ist (und wird dies wahrscheinlich nicht mehr tun).
Starturtle
12

Wie überprüfe ich, ob eine Datei vorhanden ist, ohne die try-Anweisung zu verwenden?

Im Jahr 2016 ist dies wohl immer noch der einfachste Weg, um zu überprüfen, ob sowohl eine Datei vorhanden ist als auch ob es sich um eine Datei handelt:

import os
os.path.isfile('./file.txt')    # Returns True if exists, else False

isfileist eigentlich nur eine Hilfsmethode, die intern os.statund stat.S_ISREG(mode)darunter verwendet wird. Dies os.statist eine untergeordnete Methode, mit der Sie detaillierte Informationen zu Dateien, Verzeichnissen, Sockets, Puffern und mehr erhalten. Mehr über os.stat hier

Hinweis: Dieser Ansatz sperrt die Datei jedoch in keiner Weise und daher kann Ihr Code anfällig für TOCTTOU- Fehler ( Time of Check to Time of Use ) werden.

Das Auslösen von Ausnahmen wird daher als akzeptabler und pythonischer Ansatz für die Flusskontrolle in Ihrem Programm angesehen. Und man sollte in Betracht ziehen, fehlende Dateien mit IOErrors zu behandeln, anstatt ifAnweisungen ( nur ein Ratschlag ).

Inconnu
quelle
9
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)
Khaled.K
quelle
@ j6m8 ja, isReadableFile(path,fileName)wird zurückgegeben, Truewenn die Datei vom Prozess \ program \ thread
Khaled.K