7118 Stimmen

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

Wie prüfe ich, ob eine Datei existiert oder nicht, ohne die try Aussage?

16 Stimmen

Um zu prüfen, ob ein Path-Objekt existiert, unabhängig davon, ob es sich um eine Datei oder ein Verzeichnis handelt, verwenden Sie my_path.exists() .

1 Stimmen

my_path.exists() ist nicht ausreichend. my_path.is_file() wird Ihnen sagen, ob es sich um eine Datei handelt (könnte zum Lesen gut sein). Aber wenn Sie die Datei erstellen wollen, müssen Sie auch prüfen exists schließen Sie also Verzeichnisse oder andere Dinge im Dateisystem, die keine Dateien sind, aus, die den Fehler verursachen.

0 Stimmen

Verwenden Sie os.path.isfile, um nur Dateien zu prüfen, und verwenden Sie os.path.exists, um sowohl Dateien als auch Verzeichnisse zu prüfen. Mehr dazu erfahren Sie hier: shortbuzz.in/blog/shortbuzz.in/

360voto

benefactual Punkte 6891
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

10 Stimmen

Im Allgemeinen ist es keine gute Praxis, Variablen genauso zu benennen wie Methodennamen.

310voto

CristiFati Punkte 32139

Obwohl fast alle Möglichkeiten in (mindestens einer) der vorhandenen Antworten aufgeführt sind (z.B. Python 3.4 spezifische Dinge hinzugefügt wurden), werde ich versuchen, alles zusammenzufassen.

Note : jedes Stück von Python Der Code der Standardbibliothek, den ich veröffentlichen werde, gehört zur Version 3.5.3 .

Problemstellung :

  1. Datei prüfen ( streitbar : auch Ordner ("spezielle" Datei) ?) Existenz
  2. Verwenden Sie nicht Versuchen Sie / außer / sonst / schließlich Blöcke

Mögliche Lösungen :

  1. [Python 3]: os.path. existiert ( Pfad ) (Überprüfen Sie auch andere Funktionsfamilienmitglieder wie os.path.isfile , os.path.isdir , os.path.lexists für leicht unterschiedliche Verhaltensweisen)

    os.path.exists(path)

    Rückkehr True si Pfad verweist auf einen vorhandenen Pfad oder einen offenen Dateideskriptor. Rückgabe False für defekte symbolische Links. Auf einigen Plattformen gibt diese Funktion möglicherweise False wenn keine Erlaubnis zur Ausführung erteilt wird os.stat() auf die angeforderte Datei, auch wenn die Pfad physisch existiert.

    Alles gut, aber wenn man dem Importbaum folgt:

    • 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 Versuchen Sie / außer Block um [Python 3]: os. stat ( Pfad, *, dir_fd=None, follow_symlinks=True ) . Ihr Code lautet also Versuchen Sie / außer frei, aber weiter unten im Framestack gibt es (mindestens) eine solchen Block. Dies gilt auch für andere Funktionen ( einschließlich os.path.isfile ).

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

    • Es ist ein ausgefalleneres (und mehr python ic) Art und Weise, Pfade zu behandeln, pero
    • Unter der Haube macht es genau die gleiche Sache ( 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 Anweisungskontext-Managern . Entweder:

    • Erstellen Sie eine:

      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 wiederhole die os.path.isfile Verhalten (beachten Sie, dass dies nur zu Demonstrationszwecken ist, tun no Versuch, einen solchen Code zu schreiben für Produktion ):

        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
    • Utilice [Python 3]: contextlib. unterdrücken. ( *Ausnahmen ) - das war speziell konzipiert für die selektive Unterdrückung von Ausnahmen

    Aber sie scheinen Hüllen zu sein über Versuchen Sie / außer / sonst / schließlich Blöcke, wie [Python 3]: Die mit Anweisung Staaten:

    Dies ermöglicht gemeinsame Versuchen Sie ... außer ... schließlich Nutzungsmuster zur bequemen Wiederverwendung gekapselt werden.

  3. Funktionen zur Durchquerung des Dateisystems (und Suche der Ergebnisse nach übereinstimmenden Elementen)

    Da diese über Ordner iterieren, sind sie (in den meisten Fällen) ineffizient für unser Problem (es gibt Ausnahmen, wie nicht wildcarded Globus bing - wie @ShadowRanger bemerkte), also werde ich nicht darauf bestehen. Ganz zu schweigen davon, dass in einigen Fällen die Verarbeitung von Dateinamen erforderlich sein könnte.

  4. [Python 3]: os. Zugang ( path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True ) deren Verhalten ähnlich ist wie os.path.exists (tatsächlich ist er breiter, hauptsächlich wegen der 2 und Argument)

    • Benutzerrechte könnte die "Sichtbarkeit" der Datei einschränken, wie es im Dokument heißt:

      ...prüfen, ob der aufrufende Benutzer den angegebenen Zugriff auf Pfad . Modus sollte sein F_OK um die Existenz des Pfades zu testen...

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

    Da ich auch in der C Ich verwende diese Methode ebenfalls, denn sie ruft unter der Haube einheimische API s (wiederum ü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. Wie @AaronHall richtig bemerkt hat, sollten Sie es also nur verwenden, wenn Sie wissen, was Sie tun:

    Note : Einheimische anrufen API s ist auch möglich über [Python 3]: ctypes - Eine fremde Funktionsbibliothek für Python aber in den meisten Fällen ist es komplizierter.

    ( Gewinnen Sie spezifisch): Seit vcruntime* ( msvcr* ) .dll Ausfuhren einer [MS.Docs]: _access, _waccess Funktion Familie auch, 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 os.F_OK im Aufruf, aber das dient nur der Klarheit (sein Wert ist 0 )
    • Ich benutze _waccess so dass derselbe Code auch auf Python3 y Python2 (trotz der Unicode die damit verbundenen Unterschiede zwischen ihnen)
    • Allerdings handelt es sich dabei um einen sehr spezifischen Bereich, es wurde in keiner der vorherigen Antworten erwähnt

    Le site Lnx ( Ubtu (16 x64) ) auch das Gegenstück:

    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 Hardcoding libc den Pfad ( "/lib/x86_64-linux-gnu/libc.so.6" ), die von System zu System unterschiedlich sein können (und höchstwahrscheinlich auch sein werden), Keine (oder die leere Zeichenkette) kann an CDLL Konstrukteur ( ctypes.CDLL(None).access(b"/tmp", os.F_OK) ). Nach [man7]: DLOPEN(3) :

      Si Dateiname NULL ist, dann ist der zurückgegebene Handle für die Haupt Programm. Bei der Übergabe an dlsym () wird mit diesem Handle eine Suche nach einem Symbol im Hauptprogramm, gefolgt von allen gemeinsam genutzten Objekten, die beim Programmstart geladen wurden, und dann alle gemeinsam genutzten Objekte, die von dlopen () mit dem Kennzeichen RTLD_GLOBAL .

      • Hauptprogramm (aktuell) ( python ) ist verknüpft mit libc so dass seine Symbole (einschließlich Zugang ) wird geladen
      • Dies ist mit Vorsicht zu genießen, da Funktionen wie Haupt , Py_Main und (alle) anderen sind verfügbar; sie aufzurufen, könnte katastrophale Auswirkungen (auf das laufende Programm) haben
      • Dies gilt auch nicht für Gewinnen Sie (aber das ist nicht so schlimm, denn msvcrt.dll befindet sich in %SystemRoot%". \System32 " die sich in %PATH%. standardmäßig). Ich wollte die Sache noch weiter treiben und dieses Verhalten auf folgende Weise reproduzieren Gewinnen Sie (und einen Patch einreichen), aber es stellt sich heraus, [MS.Docs]: Funktion GetProcAddress nur "sieht" exportiert Symbole, d.h. wenn nicht jemand die Funktionen in der ausführbaren Hauptdatei als __declspec(dllexport) (warum in aller Welt die regelmäßig Person würde das tun?), das Hauptprogramm ist zwar ladbar, aber so gut wie unbrauchbar
  5. Installieren Sie ein Modul eines Drittanbieters mit Dateisystemfunktionen

    Höchstwahrscheinlich wird sie sich auf eine der oben genannten Möglichkeiten verlassen (vielleicht mit leichten Anpassungen).
    Ein Beispiel wäre (wiederum, Gewinnen Sie spezifisch) [GitHub]: mhammond/pywin32 - Python für Windows (pywin32) Erweiterungen die ein Python Umhüllung über WINAPI s.

    Da dies aber eher eine Notlösung ist, höre ich hier auf.

  6. Eine andere (lahme) Abhilfe ( gainarie ) ist (wie ich es gerne nenne) die sysadmin Ansatz: Verwendung Python als Wrapper zur Ausführung von Shell-Befehlen

    • Gewinnen Sie :

      (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

Unterm Strich :

  • Do verwenden. Versuchen Sie / außer / sonst / schließlich Blöcke, denn sie können verhindern, dass man auf eine Reihe von unangenehmen Problemen stößt. Ein Gegenbeispiel, das mir einfällt, ist die Leistung: Solche Blöcke sind kostspielig, also versuchen Sie, sie nicht in Code einzubauen, der Hunderttausende Male pro Sekunde ausgeführt werden soll (da er aber (in den meisten Fällen) Plattenzugriffe beinhaltet, wird das nicht der Fall sein).

Schlussbemerkung(en) :

  • Ich werde versuchen, sie auf dem neuesten Stand zu halten, Vorschläge sind willkommen, und ich werde alles Nützliche, das mir einfällt, in die Antwort einbauen.

3 Stimmen

Können Sie diese Aussage näher erläutern? "Obwohl es keine gute Praxis ist, verwende ich os.F_OK in dem Aufruf, aber das ist nur der Klarheit halber (sein Wert ist 0)"

7 Stimmen

@sk8asd123: Es ist etwas schwierig, das in einem Kommentar zu schreiben: Im Allgemeinen ist es am besten, Konstanten mit Funktionen zu verwenden, mit denen sie zusammenkommen. Das gilt, wenn man mit mehreren Modulen arbeitet, die dieselbe Konstante definieren, denn einige könnten nicht auf dem neuesten Stand sein, und es ist am besten, wenn die Funktionen und Konstanten synchronisiert sind. Bei der Arbeit mit ctypes (direkter Aufruf der Funktionen) hätte ich die Konstante (aus MSDN ), oder überhaupt keine Konstante verwenden. Es ist nur eine Richtlinie, die ich verwende, in 99,9% macht es wahrscheinlich keinen Unterschied (funktional).

5 Stimmen

@CristiFati: Ab dem 3.6, glob.iglob (und glob.glob auch) basieren auf os.scandir Um den ersten Treffer in einem Verzeichnis mit 10 Mio. Dateien zu finden, scannen Sie nur so lange, bis Sie den ersten Treffer erreicht haben. Und sogar vor 3.6, wenn Sie glob Methoden ohne Platzhalter, ist die Funktion intelligent: Sie weiß, dass es nur einen Treffer geben kann, also wird das Globbing vereinfacht, so dass nur noch os.path.isdir o os.path.lexists (je nachdem, ob der Pfad mit / ).

220voto

Cody Piersall Punkte 7794

Python 3.4+ verfügt über ein objektorientiertes Pfadmodul: pathlib . Mit diesem neuen Modul können Sie wie folgt prüfen, ob eine Datei existiert:

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) weiterhin eine try/except Block beim Öffnen von Dateien:

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

Das pathlib-Modul hat eine Menge cooler Sachen drauf: bequemes Globbing, Überprüfung des Dateibesitzers, einfacheres Verbinden von Pfaden, usw. Es lohnt sich, es auszuprobieren. Wenn Sie ein älteres Python verwenden (Version 2.6 oder später), können Sie pathlib trotzdem 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

0 Stimmen

Sie können verwenden pathlib.Path.exists die mehr Fälle abdeckt als is_file

174voto

un33k Punkte 16338

Dies ist der einfachste Weg, um zu prüfen, ob eine Datei existiert. Einfach denn die Datei existierte, als Sie sie prüften, nicht Garantie dass er da ist, wenn Sie ihn ö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")

18 Stimmen

Solange Sie beabsichtigen, auf die Datei zuzugreifen, ist die Race Condition gibt es unabhängig davon, wie Ihr Programm aufgebaut ist. Ihr Programm kann nicht garantieren, dass ein anderer Prozess auf dem Computer die Datei nicht verändert hat. Dies bezeichnet Eric Lippert als eine exogene Ausnahme . Sie können dies nicht vermeiden, indem Sie vorher prüfen, ob die Datei vorhanden ist.

1 Stimmen

@IsaacSupeene Die beste Praxis besteht darin, das Fenster für (Datei-)Operationen so klein wie möglich zu halten, gefolgt von einer angemessenen Ausnahmebehandlung

0 Stimmen

Am besten wäre es, die Datei mit try+catch zu öffnen, wobei es kein Zeitfenster gibt.

144voto

Wie prüfe ich mit Python, ob eine Datei existiert, ohne eine try-Anweisung zu verwenden?

Jetzt verfügbar seit Python 3.4, importieren und instanziieren Sie eine Path Objekt mit dem Dateinamen, und prüfen Sie die is_file Methode (beachten Sie, dass diese auch für Symlinks, die auf reguläre Dateien verweisen, True zurückgibt):

>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False

Wenn Sie Python 2 verwenden, können Sie das pathlib-Modul von pypi zurückportieren, pathlib2 oder anderweitig prüfen isfile von der os.path Modul:

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

Nun ist das oben genannte wahrscheinlich die beste pragmatische direkte Antwort hier, aber es gibt die Möglichkeit einer Race-Condition (je nachdem, was Sie versuchen zu erreichen), und die Tatsache, dass die zugrunde liegende Implementierung verwendet eine try , aber Python verwendet try überall in seiner Umsetzung.

Da Python die try gibt es eigentlich keinen Grund, eine Implementierung zu vermeiden, die sie verwendet.

Der Rest dieser Antwort versucht jedoch, diese Vorbehalte zu berücksichtigen.

Längere, viel pedantischere Antwort

Verfügbar seit Python 3.4, verwenden Sie die neue Path Objekt in pathlib . Beachten Sie, dass .exists ist nicht ganz richtig, denn Verzeichnisse sind keine Dateien (außer in dem Unix-Sinn, dass todo ist eine Datei).

>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True

Wir müssen also Folgendes 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).

Nehmen wir 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, NamedTemporaryFile löscht die Datei, wenn sie geschlossen wird (und schließt sie automatisch, wenn es keine Verweise mehr auf sie gibt).

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

Wenn Sie sich mit die Umsetzung Sie werden jedoch feststellen, 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 mögen try weil es Race Conditions vermeidet. Mit try Sie versuchen einfach, Ihre Datei zu lesen, in der Erwartung, dass sie vorhanden ist, und wenn nicht, fangen Sie die Ausnahme ab und führen das Fallback-Verhalten aus, das sinnvoll ist.

Wenn Sie prüfen wollen, ob eine Datei vorhanden ist, bevor Sie versuchen, sie zu lesen, und Sie sie möglicherweise löschen und mehrere Threads oder Prozesse verwenden oder ein anderes Programm von dieser Datei weiß und sie löschen könnte, riskieren Sie einen Rennbedingung wenn Sie prüfen, ob es existiert, denn Sie sind dann Rennsport zu öffnen, bevor die Zustand (seine Existenz) ändert.

Race Conditions sind sehr schwer zu debuggen, weil es ein sehr kleines Zeitfenster gibt, in dem sie das Programm zum Scheitern bringen können.

Aber wenn das Ihre Motivation ist, sollten Sie puede den Wert von a erhalten try Anweisung durch Verwendung der suppress Kontext-Manager.

Vermeiden von Race Conditions ohne Try-Anweisung: suppress

Python 3.4 gibt uns die suppress Kontextmanager (früher der ignore Kontextmanager), der semantisch genau das Gleiche in weniger Zeilen leistet und gleichzeitig (zumindest oberflächlich) die ursprüngliche Forderung erfüllt, eine try Erklärung:

from contextlib import suppress
from pathlib import Path

Verwendung:

>>> 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 eigenen Rollen verwenden suppress , aber ohne eine try wird ausführlicher sein als mit. Ich glaube dies ist die einzige Antwort, die nicht die try auf einer beliebigen Ebene in der Python die vor Python 3.4 angewendet werden kann, weil sie stattdessen einen Kontextmanager verwendet:

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 ist es mit einem Versuch einfacher:

from contextlib import contextmanager

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

Andere Optionen, die die Forderung nach "ohne Versuch" nicht erfüllen:

isfile

import os
os.path.isfile(path)

von der docs :

os.path.isfile(path)

Gibt True zurück, wenn der Pfad eine bestehende reguläre Datei ist. Dies folgt symbolischen Links, so dass sowohl islink() y isfile() für denselben Pfad wahr sein kann.

Aber wenn man sich die Quelle dieser Funktion sehen Sie, 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

Alles, was er tut, ist, den angegebenen Pfad zu verwenden, um zu sehen, ob er Statistiken über ihn erhalten kann, indem er OSError und prüft dann, ob es sich um eine Datei handelt, wenn sie keine Ausnahme ausgelöst hat.

Wenn Sie beabsichtigen, etwas mit der Datei zu tun, würde ich vorschlagen, es direkt mit einem try-except zu versuchen, um eine Race Condition 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 zu verwenden, aber Sie müssen Flags übergeben, und es wird nicht zwischen Dateien und Verzeichnissen unterschieden. Dies wird eher dazu verwendet, um zu testen, ob der aufrufende Benutzer in einer Umgebung mit erhöhten Rechten Zugriff hat:

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

Es leidet auch unter denselben Problemen mit Race Conditions wie isfile . Von der docs :

Anmerkung: Die Verwendung von access() zur Überprüfung, ob ein Benutzer berechtigt ist, z.B. eine Datei zu öffnen zu öffnen, bevor er dies mit open() tatsächlich tut, schafft eine Sicherheitslücke, weil denn der Benutzer könnte die kurze Zeitspanne zwischen der Überprüfung und dem Öffnen der Datei ausnutzen, um sie zu manipulieren. Es ist vorzuziehen, EAFP Techniken. 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 handelt sich um eine Funktion auf niedriger Ebene, bei der mehr Möglichkeiten für Benutzerfehler bestehen als bei den oben beschriebenen Objekten und Funktionen auf höherer Ebene.

Kritik an einer anderen Antwort:

Eine andere Antwort sagt dies über os.access :

Ich persönlich bevorzuge diese Variante, weil sie unter der Haube native APIs aufruft (über "${PYTHON_SRC_DIR}/Modules/posixmodule.c"), aber sie öffnet auch ein Tor für mögliche Benutzerfehler, und sie ist nicht so pythonisch wie andere Varianten:

Diese Antwort besagt, dass sie eine nicht-pythonische, fehleranfällige Methode bevorzugt, ohne dass dies begründet wird. Sie scheint die Benutzer zu ermutigen, Low-Level-APIs zu verwenden, ohne sie zu verstehen.

Außerdem wird ein Kontextmanager erstellt, der durch die bedingungslose Rückgabe von True erlaubt alle Ausnahmen (einschließlich KeyboardInterrupt y SystemExit !) stillschweigend zu passieren, was eine gute Möglichkeit ist, Fehler zu verstecken.

Dies scheint die Nutzer zu schlechten Praktiken zu verleiten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X