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




testen ob datei existiert python (24)

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"

Wie kann ich sehen, ob eine Datei existiert oder nicht, ohne die try Anweisung zu verwenden?


2017/12/22 :

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

Hinweis : Jeder Python- Standardbibliothekcode, den ich veröffentlichen werde, gehört zu Version 3.5.3 (Doc-Anführungszeichen sind Version 3- spezifisch).

Problemstellung :

  1. Überprüfen Sie das Vorhandensein von Dateien ( fraglich : auch Ordner ("spezielle" Datei)?)
  2. Verwenden Sie keine try / except / else / finally Blöcke

Mögliche Lösungen :

  1. [Python]: os.path. exists ( path ) (überprüfen Sie auch die Mitglieder anderer Funktionsfamilien wie os.path.isfile , os.path.isdir , os.path.lexists auf etwas andere Verhaltensweisen)

    os.path.exists(path)
    

    Geben Sie True wenn path sich auf einen vorhandenen Pfad oder einen offenen Dateideskriptor bezieht. Gibt für gebrochene symbolische Links False . Auf einigen Plattformen gibt diese Funktion möglicherweise False wenn keine Berechtigung zum Ausführen von os.stat() für die angeforderte Datei erteilt wird, 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 os.stat() os.stat() . Also, Ihr Code ist try/except Exception, aber im Framestack ist (zumindest) ein solcher Block. Dies gilt auch für andere Funktionen ( einschließlich os.path.isfile ).

    1.1. [Python]: pathlib.Path. is_file ()

    • Es ist eine schickere (und mehr pythonische) Art, Pfade zu handhaben, aber
    • Unter der Haube tut es genau dasselbe ( 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]: Mit Statement-Kontext-Managern . 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 repliziere das isfile Verhalten (beachten Sie, dass dies nur zu Demonstrationszwecken ist, 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]: contextlib. Unterdrückung ( * Ausnahmen ) - speziell für das selektive Unterdrücken von Ausnahmen


    Aber es scheint, als seien sie Wrapper über try/except/else/finally blockiert, da [Python]: Die with- Anweisung besagt:

    Dies ermöglicht den allgemeinen try ... mit except finally Verwendung von Verwendungsmustern für eine bequeme Wiederverwendung.

  3. Dateisystem-Durchlauffunktionen (und Durchsuchen der Ergebnisse nach übereinstimmenden Elementen)


    Da diese Ordner durchlaufen werden (in den meisten Fällen), sind sie für unser Problem ineffizient (es gibt Ausnahmen, z. B. nicht mit Platzhalter versehenes Globing - wie @ShadowRanger darauf hinweist), so dass ich nicht darauf bestehe. Ganz zu schweigen davon, dass in einigen Fällen die Verarbeitung von Dateinamen erforderlich sein kann.

  4. [Python]: os. Zugriff ( Pfad, Modus, *, dir_fd = Keiner, effektive_Daten = Falsch, follow_symlinks = True ), dessen Verhalten nahe an os.path.exists (tatsächlich ist es breiter, hauptsächlich aufgrund des 2. Arguments)

    • Benutzerberechtigungen können die Sichtbarkeit der Datei einschränken, da das Dokument Folgendes angibt:

      ... testen, ob der aufrufende Benutzer den angegebenen Pfad hat . Modus sollte F_OK , um das Vorhandensein von Pfad zu testen ...

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

    Da ich auch in C arbeite, verwende ich diese Methode auch, da sie unter der Haube native APIs aufruft (wiederum über "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c" ), aber auch ein Tor für mögliche Benutzer öffnet Fehler , und es ist nicht so Python ic wie andere Varianten. Wie @AaronHall zu Recht darauf hinweist, verwenden Sie es also nur, wenn Sie wissen, was Sie tun:

    Hinweis : Der Aufruf nativer APIs ist auch über [Python] möglich: ctypes - Eine fremde Funktionsbibliothek für Python , in den meisten Fällen jedoch komplizierter.

    ( Win- spezifisch): Da msvcr * ( vcruntime * ) auch eine [MSDN]: _access, _waccess- Funktionsfamilie exportiert, ist 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", os.F_OK)
    -1
    

    Anmerkungen :

    • Obwohl dies keine gute Praxis ist, verwende ich os.F_OK im Aufruf. os.F_OK ist jedoch nur der Klarheit os.F_OK (der Wert ist 0 ).
    • Ich verwende _waccess damit derselbe Code für Python3 und Python2 funktioniert (trotz Unicode- Unterschieden).
    • Obwohl dies ein sehr spezifisches Gebiet betrifft, wurde es in keiner der vorherigen Antworten erwähnt


    Das Gegenstück zu Lnx ( Ubtu (16 x64) ) ebenfalls:

    Python 3.5.2 (default, Nov 17 2016, 17:05:23)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK)
    0
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp1", os.F_OK)
    -1
    

    Anmerkungen :

    • Stattdessen kann der Pfad von libc ( "/lib/x86_64-linux-gnu/libc.so.6" ) hartcodiert werden, der (und wird höchstwahrscheinlich) systemübergreifend variieren können, None (oder der leere String) an den CDLL Konstruktor übergeben werden ( ctypes.CDLL(None).access(b"/tmp", os.F_OK) ). Nach [Mann]: DLOPEN (3) :

      Wenn Dateiname NULL ist, gilt das zurückgegebene Handle für das Hauptprogramm. Wenn dieses Handle an dlsym () übergeben wird, sucht dieses Handle nach einem Symbol im Hauptprogramm, gefolgt von allen gemeinsam genutzten Objekten, die beim Programmstart geladen wurden. Anschließend werden alle von dlopen () geladenen gemeinsam genutzten Objekte mit dem Flag RTLD_GLOBAL angezeigt .

      • Hauptprogramm (aktuelles Programm) ( Python ) ist mit libc verknüpft, so dass seine Symbole (einschließlich access ) geladen werden
      • Dies ist mit Vorsicht zu Py_Main , da Funktionen wie main , Py_Main und (alle) andere verfügbar sind; Aufruf 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 sich standardmäßig in % PATH% befindet ). Ich wollte die Dinge weiter ausführen und dieses Verhalten unter Win replizieren (und einen Patch einreichen), aber wie sich herausstellt, "sieht" die GetProcAddress-Funktion nur exportierte Symbole, es sei denn, jemand deklariert die Funktionen in der Hauptprogrammdatei als __declspec(dllexport) (warum in __declspec(dllexport) Welt würde das eine normale Person tun?), das Hauptprogramm ist ladbar, aber ziemlich unbrauchbar
  5. Installieren Sie ein Drittanbieter- Modul mit Dateisystemfunktionen

    Am wahrscheinlichsten wird eine der oben genannten Möglichkeiten sein (möglicherweise mit geringfügigen Anpassungen).
    Ein Beispiel wäre (wieder Win- spezifisch) [GitHub]: Python für Windows (pywin32) -Erweiterungen , bei dem es sich um einen Python- Wrapper über WINAPIs handelt .

    Da dies jedoch eher eine Problemumgehung ist, halte ich hier an.

  6. Ein weiterer (lahmer) Workaround ( Gainarie ) ist (wie ich es gerne nenne) der sysadmin- Ansatz: Verwenden Sie Python als Wrapper, um Shell-Befehle auszuführen

    • Win :

      (py35x64_test) e:\Work\Dev\\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\\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe.notexist\" > nul 2>&1'))"
      1
      
    • Lnx ( Ubtu ):

      [[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
      

Fazit :

  • Verwenden Sie try / except / else / finally Blöcke, da diese verhindern können, dass Sie auf eine Reihe von unangenehmen Problemen stoßen. Ein Gegenbeispiel, das ich mir vorstellen kann, ist die Leistung: Solche Blöcke sind teuer, also versuchen Sie, sie nicht in Code zu platzieren, der Hunderttausende Male pro Sekunde laufen soll (aber da dies in den meisten Fällen einen Plattenzugriff erfordert). 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 aufnehmen, das in die Antwort aufgenommen wird


Dies ist der einfachste Weg, um zu prüfen, ob eine Datei existiert. Nur weil die Datei beim Prüfen 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")

if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

Das Erheben von Ausnahmen gilt als akzeptabler Ansatz für die Flusskontrolle in Ihrem Programm und Pythonic. 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


Im Gegensatz zu isfile() gibt exists() für Verzeichnisse True .
Abhängig davon, ob Sie nur einfache Dateien oder auch Verzeichnisse wünschen, 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

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 aufgrund seiner Existenz als wahr oder falsch zurückgegeben.


Sie haben die os.path.exists Funktion:

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

Dies gibt True für Dateien und Verzeichnisse zurück. Sie können jedoch stattdessen verwenden

os.path.isfile(file_path)

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


Testen auf Dateien und Ordner 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() , um die Erweiterung zu erhalten (wenn 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

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 Sie einfacher mit Ihrem Betriebssystem navigieren und Standardaktionen ausführen.

Weitere Informationen finden Sie unter share

Wenn Sie Vorgänge auf hoher Ebene benötigen, verwenden Sie shutil .


Python 3.4+ verfügt über ein objektorientiertes pathlib : 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 dies normalerweise tun) beim Öffnen von Dateien immer noch einen try/except 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 Dateieigentümers, einfacheres Einfügen von Pfaden usw. Es lohnt sich, dies zu überprüfen. Wenn Sie mit einem älteren Python (Version 2.6 oder höher) arbeiten, können Sie weiterhin pathlib mit pip installieren:

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

Dann importieren Sie es wie folgt:

# Older Python versions
import pathlib2 as pathlib

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 von dort aus weiterlaufen, oder Sie können es programmieren, um es zu stoppen, wenn Sie möchten.


Hier ist ein einzeiliger Python-Befehl für die Linux-Befehlszeilenumgebung. Ich finde das SEHR HANDIG, da ich kein so heißer Kerl bin.

python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"

Ich hoffe das ist hilfreich.


Wenn der Grund dafür ist, dass Sie prüfen, dass Sie if file_exists: open_it() tun können, if file_exists: open_it() , ist es sicherer, den Versuch zu versuchen, es zu öffnen. Beim Prüfen und Öffnen besteht die Gefahr, dass die Datei gelöscht oder verschoben wird oder wenn zwischen dem Überprüfen und dem Versuch, sie zu öffnen, etwas passiert.

Wenn Sie die Datei nicht sofort öffnen os.path.isfile , können Sie os.path.isfile

Gibt True wenn der Pfad eine vorhandene reguläre Datei ist. Dies folgt symbolischen Links, so dass sowohl islink() als auch os.path.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 pathlib Modul einen objektorientierten Ansatz (Rückportierung auf pathlib2 in Python 2.7):

from pathlib import Path

my_file = Path("/path/to/file")
if my_file.is_file():
    # file exists

So prüfen Sie ein Verzeichnis:

if my_file.is_dir():
    # directory exists

Um zu prüfen, ob ein Path Objekt vorhanden ist, 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() in einem try Block verwenden:

try:
    my_abs_path = my_file.resolve()
except FileNotFoundError:
    # doesn't exist
else:
    # exists

Überprüfen Sie, ob die Datei oder das Verzeichnis vorhanden ist

Sie können diesen drei Möglichkeiten folgen:

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

Hinweis2: Wird os.path.existsfür Dateien und 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()

Ich bin der Autor eines Pakets, das seit etwa 10 Jahren existiert, und hat eine Funktion, die diese Frage direkt anspricht. Wenn Sie sich auf einem Nicht-Windows-System befinden, wird im Allgemeinen Popendarauf zugegriffen find. Wenn Sie sich jedoch unter Windows befinden, repliziert es sich findmit einem effizienten Dateisystem-Walker.

Der Code selbst verwendet keinen tryBlock… außer zur Bestimmung des Betriebssystems und damit zum "Unix" -Stil findoder zum Hand-Buillt find. Timing-Tests haben gezeigt, dass die tryErmittlung des Betriebssystems schneller war, daher habe ich dort eines verwendet (aber nirgendwo sonst).

>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']

Und das Dokument…

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


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 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 verwendet wird os.statund stat.S_ISREG(mode)darunter liegt. Dies os.statist eine untergeordnete Methode, mit der Sie detaillierte Informationen zu Dateien, Verzeichnissen, Sockets, Puffern usw. erhalten. Mehr über os.stat hier

Hinweis: Bei diesem Ansatz wird die Datei jedoch in keiner Weise gesperrt . Daher kann Ihr Code anfällig für " Time of Check to Time of Use " ( TOCTTOU ) -Fehler sein .

Das Erhöhen von Ausnahmen ist daher ein akzeptabler und Pythonic-Ansatz für die Flusskontrolle in Ihrem Programm. Und man sollte in Betracht ziehen, fehlende Dateien mit IOErrors zu behandeln, und nicht mit ifAnweisungen ( nur ein Hinweis ).


Datum: 2017-12-04

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

Es gibt folgende Möglichkeiten, um zu prüfen, ob eine Datei existiert:

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

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

Jetzt seit Python 3.4 verfügbar, importieren und instanziieren Sie ein Path Objekt mit dem Dateinamen und überprüfen Sie die is_file Methode (beachten Sie, dass dies für Symlinks zurückgibt, die ebenfalls 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 die isfile aus dem os.path Modul anderweitig prüfen:

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

Nun ist das Obige wahrscheinlich die beste pragmatische direkte Antwort hier, aber es gibt die Möglichkeit einer Race-Bedingung (abhängig davon, was Sie zu erreichen versuchen) und der Tatsache, dass die zugrunde liegende Implementierung einen try , aber Python verwendet try überall in seinem 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 Einschränkungen zu berücksichtigen.

Längere, viel pedantischere Antwort

Verwenden Sie das seit Python 3.4 verfügbare neue Path Objekt in pathlib . 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 :

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

Also lassen Sie uns eine Datei bekommen, 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 weiteren Verweise darauf vorhanden sind).

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

Wenn Sie jedoch in die Implementierung is_file , werden Sie is_file dass is_file 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 try es gerne try weil es die Rennbedingungen vermeidet. Mit try Sie einfach, Ihre Datei zu lesen und zu erwarten, dass sie vorhanden ist. Wenn nicht, fangen Sie die Ausnahme ab und führen das Fallback-Verhalten aus, das sinnvoll ist.

Wenn Sie prüfen möchten, ob eine Datei vorhanden ist, bevor Sie versuchen, sie zu lesen, löschen Sie sie möglicherweise und verwenden möglicherweise mehrere Threads oder Prozesse, oder ein anderes Programm kennt diese Datei und könnte sie löschen - Sie riskieren dies eine Rennbedingung, wenn Sie prüfen, ob sie existiert, weil Sie dann damit beginnen , sie zu öffnen, bevor sich ihr Zustand (ihre Existenz) ändert.

Rennbedingungen sind sehr schwer zu debuggen, da es ein sehr kleines Fenster gibt, in dem das Programm ausfallen kann.

Wenn dies jedoch Ihre Motivation ist, können Sie den Wert einer try Anweisung mithilfe des Kontextmanagers suppress .

Rennbedingungen ohne eine try-Anweisung vermeiden: suppress

Python 3.4 gibt uns den suppress (zuvor der ignore ), der semantisch in weniger Zeilen genau dasselbe tut, während er (zumindest oberflächlich) die ursprüngliche Anfrage erfüllt, um 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önnen Sie Ihre eigene suppress rollen, aber ohne einen try wird ausführlicher als mit. Ich glaube, dass dies tatsächlich die einzige Antwort ist, die try auf keiner Ebene in Python verwendet, 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 Nachfrage nach "ohne Versuch" nicht erfüllen:

isfile

import os
os.path.isfile(path)

aus den docs :

os.path.isfile(path)

Gibt True zurück, wenn der Pfad eine vorhandene reguläre Datei ist. Dies folgt symbolischen Links, so dass sowohl islink() als auch isfile() für denselben Pfad wahr sein können.

Wenn Sie jedoch die source dieser Funktion untersuchen, werden Sie feststellen, dass sie tatsächlich eine try-Anweisung verwendet:

# 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

Sie müssen OSError den angegebenen Pfad verwenden, um zu sehen, ob er Statistiken OSError kann, OSError und dann prüfen, ob es sich um eine Datei handelt, wenn die Ausnahme nicht OSError .

Wenn Sie beabsichtigen, etwas mit der Datei zu tun, würde ich empfehlen, es direkt mit einem Try-Exceptor zu versuchen, um eine Race-Bedingung zu vermeiden:

try:
    with open(path) as f:
        f.read()
except OSError:
    pass

os.access

Für Unix und Windows ist os.access verfügbar. Für die Verwendung müssen jedoch Flags übergeben werden, wobei zwischen Dateien und Verzeichnissen nicht unterschieden wird. Dies wird eher verwendet, um zu testen, ob der echte aufrufende Benutzer in einer Umgebung mit erhöhten Berechtigungen Zugriff hat:

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

Es hat auch die gleichen Probleme mit dem isfile wie bei isfile . Aus den docs :

Hinweis: Wenn Sie mit access () prüfen, ob ein Benutzer berechtigt ist, z. B. eine Datei zu öffnen, bevor Sie mit open () tatsächlich eine Sicherheitslücke erstellen, kann der Benutzer die kurze Zeitspanne zwischen dem Überprüfen und Öffnen der Datei für die Bearbeitung nutzen. 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 folgendes über os.access :

Ich persönlich bevorzuge 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 ist nicht so Pythonic wie andere Varianten :

Diese Antwort sagt, dass es eine nicht-Pythonic-Methode ohne Fehler bevorzugt, ohne Rechtfertigung. Es scheint die Benutzer zu ermutigen, APIs auf niedriger Ebene zu verwenden, ohne sie zu verstehen.

Außerdem wird ein Kontextmanager erstellt, der durch die bedingungslose Rückgabe von True alle Ausnahmen (einschließlich KeyboardInterrupt und SystemExit !) Im SystemExit passieren lässt. SystemExit ist ein guter Weg, um Fehler zu verbergen.

Dies scheint die Benutzer zu ermutigen, schlechte Praktiken anzuwenden.


import os.path

if os.path.isfile(filepath):

In Python 3.4 bietet die Sprache ein neues Modul zum Verwalten von Dateien:

import pathlib
path = pathlib.Path('path/to/file')
if path.is_file(): # If you want to check a directory: path.is_dir()
    # If it is true, return true on your code.

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

In 2016 ist der beste Weg noch os.path.isfile :

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

Oder in Python 3 können Sie pathlib :

import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
    ...

Sie können Brians Vorschlag ohne schreiben try:.

from contextlib import suppress

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

suppressist ein Teil von Python 3.4. In älteren Releases können Sie schnell eigene Unterdrückung schreiben:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass






file-exists