exception liste - Wie kann ich sicher ein verschachteltes Verzeichnis in Python erstellen?




array ordner (21)

In Python3 unterstützt os.makedirs die Einstellung exist_ok . Die Standardeinstellung ist False . OSError bedeutet, dass ein OSError wird, wenn das Zielverzeichnis bereits vorhanden ist. Wenn Sie exist_ok auf True , wird OSError (Verzeichnis existiert) ignoriert und das Verzeichnis wird nicht erstellt.

os.makedirs(path,exist_ok=True)

In Python2 unterstützt os.makedirs die Einstellung exist_ok . Sie können den Ansatz in der Antwort von heikki-toivonen verwenden :

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise

Was ist der eleganteste Weg, um zu überprüfen, ob das Verzeichnis, in das eine Datei geschrieben werden soll, vorhanden ist, und wenn nicht, erstellen Sie das Verzeichnis mit Python? Folgendes habe ich ausprobiert:

import os

file_path = "/my/directory/filename.txt"
directory = os.path.dirname(file_path)

try:
    os.stat(directory)
except:
    os.mkdir(directory)       

f = file(filename)

Irgendwie habe ich os.path.exists vermisst (danke Kanja, Blair und Douglas). Das habe ich jetzt:

def ensure_dir(file_path):
    directory = os.path.dirname(file_path)
    if not os.path.exists(directory):
        os.makedirs(directory)

Gibt es eine Flagge für "offen", damit dies automatisch geschieht?


Überprüfen Sie os.makedirs : (Es stellt sicher, dass der vollständige Pfad vorhanden ist.)
Fangen Sie OSError ab, um die Tatsache zu behandeln, dass das Verzeichnis möglicherweise vorhanden ist. (Wenn exist_ok False ist (Standardeinstellung), wird ein OSError ausgelöst, wenn das Zielverzeichnis bereits vorhanden ist.)

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass

Ich fand dieses Q / A und war anfangs verwirrt von einigen Fehlern und Fehlern, die ich bekam. Ich arbeite in Python 3 (Version 3.5 in einer virtuellen Anaconda-Umgebung auf einem Arch Linux x86_64-System).

Betrachten Sie diese Verzeichnisstruktur:

└── output/         ## dir
   ├── corpus       ## file
   ├── corpus2/     ## dir
   └── subdir/      ## dir

Hier sind meine Experimente / Notizen, die Dinge klären:

# ----------------------------------------------------------------------------
# [1] https://.com/questions/273192/how-can-i-create-a-directory-if-it-does-not-exist

import pathlib

""" Notes:
        1.  Include a trailing slash at the end of the directory path
            ("Method 1," below).
        2.  If a subdirectory in your intended path matches an existing file
            with same name, you will get the following error:
            "NotADirectoryError: [Errno 20] Not a directory:" ...
"""
# Uncomment and try each of these "out_dir" paths, singly:

# ----------------------------------------------------------------------------
# METHOD 1:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but no file created (os.makedirs creates dir, not files!  ;-)
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# [2] https://docs.python.org/3/library/os.html#os.makedirs

# Uncomment these to run "Method 1":

#directory = os.path.dirname(out_dir)
#os.makedirs(directory, mode=0o777, exist_ok=True)

# ----------------------------------------------------------------------------
# METHOD 2:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## works
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## works
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but creates a .../doc.txt./ dir
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# Uncomment these to run "Method 2":

#import os, errno
#try:
#       os.makedirs(out_dir)
#except OSError as e:
#       if e.errno != errno.EEXIST:
#               raise
# ----------------------------------------------------------------------------

Fazit: "Methode 2" ist meiner Meinung nach robuster.

[1] Wie kann ich ein Verzeichnis erstellen, wenn es nicht existiert?

[2] os.makedirs


Rufen Sie die Funktion create_dir()am Einstiegspunkt Ihres Programms / Projekts auf.

import os

def create_dir(directory):
    if not os.path.exists(directory):
        print('Creating Directory '+directory)
        os.makedirs(directory)

create_dir('Project directory')

Ausgehend von Python 3.5 hat pathlib.Path.mkdir ein exist_ok Flag:

from pathlib import Path
path = Path('/my/directory/filename.txt')
path.parent.mkdir(parents=True, exist_ok=True) 
# path.parent ~ os.path.dirname(path)

Dadurch wird das Verzeichnis rekursiv erstellt und es wird keine Ausnahme ausgelöst, wenn das Verzeichnis bereits vorhanden ist.

(So ​​wie os.makedirs ab python 3.2 ein exists_ok Flag erhalten hat).


Ich sah Heikki Toivonen und share Antworten und dachte an diese Variation.

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST or not os.path.isdir(path):
            raise

Sie können mkpath

# Create a directory and any missing ancestor directories. 
# If the directory already exists, do nothing.

from distutils.dir_util import mkpath
mkpath("test")    

Beachten Sie, dass auch die Vorfahrverzeichnisse erstellt werden.

Es funktioniert für Python 2 und 3.


Ich sehe zwei Antworten mit guten Qualitäten, jede mit einem kleinen Fehler, also werde ich meine Meinung dazu geben:

Probieren Sie os.path.exists und berücksichtigen Sie os.makedirs für die Erstellung.

import os
if not os.path.exists(directory):
    os.makedirs(directory)

Wie in Kommentaren und anderswo erwähnt, gibt es eine Race-Bedingung: Wenn das Verzeichnis zwischen den os.path.exists und den os.makedirs Aufrufen erstellt wird, os.makedirs die os.makedirs mit einem OSError . Unglücklicherweise ist OSError und das Fortsetzen nicht idiotensicher, da es einen Fehler beim Erstellen des Verzeichnisses aufgrund anderer Faktoren wie unzureichende Berechtigungen, volle Festplatte usw. ignoriert.

Eine Option wäre, den OSError und den eingebetteten Fehlercode zu untersuchen (siehe Gibt es eine plattformübergreifende Methode, um Informationen von Pythons OSError zu erhalten ):

import os, errno

try:
    os.makedirs(directory)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

Alternativ könnte es eine zweite os.path.exists . Nehmen os.path.exists jedoch an, ein anderer os.path.exists hat das Verzeichnis nach der ersten Prüfung erstellt und dann vor der zweiten entfernt. Wir könnten uns trotzdem täuschen.

Je nach Anwendung kann die Gefahr gleichzeitiger Vorgänge mehr oder weniger als die Gefahr sein, die von anderen Faktoren wie Dateiberechtigungen ausgeht. Der Entwickler muss vor der Auswahl einer Implementierung mehr über die zu entwickelnde Anwendung und die erwartete Umgebung erfahren.


Die entsprechende Python-Dokumentation schlägt die Verwendung des EAFP-Codierungsstils vor (Leichter als um Erlaubnis zu bitten) . Dies bedeutet, dass der Code

try:
    os.makedirs(path)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise
    else:
        print "\nBE CAREFUL! Directory %s already exists." % path

ist besser als die Alternative

if not os.path.exists(path):
    os.makedirs(path)
else:
    print "\nBE CAREFUL! Directory %s already exists." % path

Die Dokumentation legt dies aufgrund der in dieser Frage behandelten Race-Bedingung nahe. Darüber hinaus gibt es, wie andere hier erwähnen, einen Leistungsvorteil, wenn das Betriebssystem einmal und nicht zweimal geprüft wird. Schließlich kann das Argument, das möglicherweise zugunsten des zweiten Codes vorgetragen wird, in einigen Fällen - wenn der Entwickler die Umgebung kennt, in der die Anwendung ausgeführt wird - nur in dem speziellen Fall befürwortet werden, für den das Programm eine private Umgebung eingerichtet hat selbst (und andere Instanzen desselben Programms).

Auch in diesem Fall ist dies eine schlechte Praxis und kann zu langem, unbrauchbarem Debugging führen. Zum Beispiel sollte die Tatsache, dass wir die Berechtigungen für ein Verzeichnis festlegen, nicht dazu führen, dass die Impressionsberechtigungen für unsere Zwecke entsprechend festgelegt werden. Ein übergeordnetes Verzeichnis könnte mit anderen Berechtigungen bereitgestellt werden. Im Allgemeinen sollte ein Programm immer korrekt funktionieren und der Programmierer sollte keine bestimmte Umgebung erwarten.


Ich würde persönlich empfehlen, dass Sie os.path.isdir() anstelle von os.path.exists() zum Testen verwenden.

>>> os.path.exists('/tmp/dirname')
True
>>> os.path.exists('/tmp/dirname/filename.etc')
True
>>> os.path.isdir('/tmp/dirname/filename.etc')
False
>>> os.path.isdir('/tmp/fakedirname')
False

Wenn Sie haben:

>>> dir = raw_input(":: ")

Und eine dumme Benutzereingabe:

:: /tmp/dirname/filename.etc

... Sie erhalten am Ende ein Verzeichnis namens filename.etc wenn Sie dieses Argument an os.makedirs() wenn Sie mit os.path.exists() testen.


Verwenden Sie diesen Befehl check und erstellen Sie ein Verzeichnis

 if not os.path.isdir(test_img_dir):
     os.mkdir(str("./"+test_img_dir))

Für eine IPython.utils.path.ensure_dir_exists() können Sie IPython.utils.path.ensure_dir_exists() :

from IPython.utils.path import ensure_dir_exists
ensure_dir_exists(dir)

Aus der documentation : Stellen Sie sicher, dass ein Verzeichnis vorhanden ist. Wenn es nicht existiert, versuchen Sie, es zu erstellen, und schützen Sie sich vor einer Race-Bedingung, wenn ein anderer Prozess dasselbe tut.


import os
if os.path.isfile(filename):
    print "file exists"
else:
    "Your code here"

Wo sich Ihr Code hier befindet, verwenden Sie den Befehl (Touch)

Dadurch wird geprüft, ob die Datei vorhanden ist. Ist dies nicht der Fall, wird sie erstellt.


Sie können os.listdir dafür verwenden:

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')

Wenn Sie folgendes beachten:

os.path.isdir('/tmp/dirname')

bedeutet, dass ein Verzeichnis (Pfad) vorhanden ist UND ein Verzeichnis ist. Also für mich macht dieser Weg das, was ich brauche. So kann ich sicherstellen, dass es Ordner ist (keine Datei) und existiert.


Einblicke in die Besonderheiten dieser Situation

Sie geben eine bestimmte Datei an einem bestimmten Pfad an und ziehen das Verzeichnis aus dem Dateipfad. Nachdem Sie sichergestellt haben, dass Sie über das Verzeichnis verfügen, versuchen Sie, eine Datei zum Lesen zu öffnen. Um diesen Code zu kommentieren:

filename = "/my/directory/filename.txt"
dir = os.path.dirname(filename)

Wir möchten vermeiden, dass die eingebaute Funktion, dh, überschrieben wird. filepath oder fullfilepath ist wahrscheinlich ein besserer semantischer Name als filename daher wäre dies besser geschrieben:

import os
filepath = '/my/directory/filename.txt'
directory = os.path.dirname(filepath)

Ihr Endziel ist es, diese Datei, wie Sie anfangs angeben, zum Schreiben zu öffnen, aber Sie nähern sich diesem Ziel (basierend auf Ihrem Code) wie folgt, wodurch die Datei zum Lesen geöffnet wird:

if not os.path.exists(directory):
    os.makedirs(directory)
f = file(filename)

Vorausgesetzt Öffnung zum Lesen

Warum sollten Sie ein Verzeichnis für eine Datei erstellen, von der Sie erwarten, dass sie dort ist und lesen kann?

Versuchen Sie einfach, die Datei zu öffnen.

with open(filepath) as my_file:
    do_stuff(my_file)

Wenn das Verzeichnis oder die Datei nicht vorhanden ist, erhalten Sie einen IOError mit einer zugehörigen Fehlernummer: errno.ENOENT zeigt unabhängig von Ihrer Plattform auf die richtige Fehlernummer. Sie können es fangen, wenn Sie möchten, zum Beispiel:

import errno
try:
    with open(filepath) as my_file:
        do_stuff(my_file)
except IOError as error:
    if error.errno == errno.ENOENT:
        print 'ignoring error because directory or file is not there'
    else:
        raise

Angenommen, wir öffnen uns zum Schreiben

Das ist wahrscheinlich was Sie wollen.

In diesem Fall haben wir wahrscheinlich keine Rennbedingungen. Also machen Sie einfach so, wie Sie waren, aber beachten Sie, dass Sie zum Schreiben mit dem Modus w (oder a anhängenden) öffnen müssen. Es ist auch eine bewährte Methode in Python, den Kontext-Manager zum Öffnen von Dateien zu verwenden.

import os
if not os.path.exists(directory):
    os.makedirs(directory)
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

Angenommen, wir haben mehrere Python-Prozesse, die versuchen, alle ihre Daten in dasselbe Verzeichnis zu legen. Dann kann es zu Konflikten bei der Erstellung des Verzeichnisses kommen. In diesem Fall makedirs den makedirs Aufruf am besten in einen Try- makedirs -Block.

import os
import errno
if not os.path.exists(directory):
    try:
        os.makedirs(directory)
    except OSError as error:
        if error.errno != errno.EEXIST:
            raise
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

In Python 3.4 können Sie auch das brandneue pathlib Modul verwenden :

from pathlib import Path
path = Path("/my/directory/filename.txt")
try:
    if not path.parent.exists():
        path.parent.mkdir(parents=True)
except OSError:
    # handle error; you can also catch specific errors like
    # FileExistsError and so on.

Ich verwende os.path.exists() , here ist ein Python 3-Skript, mit dem überprüft werden kann, ob ein Verzeichnis vorhanden ist, ein Verzeichnis erstellt wird, wenn es nicht vorhanden ist, und es gelöscht wird, falls es vorhanden ist (falls gewünscht).

Es fordert Benutzer zur Eingabe des Verzeichnisses auf und kann leicht geändert werden.


Prüfen Sie, ob ein Verzeichnis existiert und erstellen Sie es ggf.?

Die direkte Antwort auf diese Frage lautet, eine einfache Situation vorauszusetzen, in der Sie nicht erwarten, dass andere Benutzer oder Prozesse Ihr Verzeichnis durcheinander bringen:

if not os.path.exists(d):
    os.makedirs(d)

oder wenn das Erstellen des Verzeichnisses Race-Bedingungen unterliegt (dh wenn nach der Überprüfung des Pfads ein anderer Pfad bereits erstellt wurde), machen Sie Folgendes:

import errno
try:
    os.makedirs(d)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise

Ein noch besserer Ansatz ist es jedoch, das Problem mit Ressourcenkonflikten zu umgehen, indem temporäre Verzeichnisse über tempfile :

import tempfile

d = tempfile.mkdtemp()

Hier ist das Wesentliche aus dem Online-Dokument:

mkdtemp(suffix='', prefix='tmp', dir=None)
    User-callable function to create and return a unique temporary
    directory.  The return value is the pathname of the directory.

    The directory is readable, writable, and searchable only by the
    creating user.

    Caller is responsible for deleting the directory when done with it.

Neu in Python 3.5: pathlib.Path mit exist_ok

Es gibt ein neues Path Objekt (ab 3.4) mit vielen Methoden, die man mit Pfaden verwenden möchte - eine davon ist mkdir .

(Im Kontext verfolge ich meine wöchentliche Wiederholung mit einem Skript. Hier sind die relevanten Teile des Codes aus dem Skript, die es mir ermöglichen, zu vermeiden, dass für dieselben Daten mehr als einmal am Tag getroffen wird.)

Zuerst die relevanten Importe:

from pathlib import Path
import tempfile

Wir müssen uns jetzt nicht mit os.path.join befassen - verbinden Sie einfach os.path.join mit einem / :

directory = Path(tempfile.gettempdir()) / 'sodata'

Dann vergewissere ich mich idempotently, dass das Verzeichnis existiert - das Argument exist_ok in Python 3.5:

directory.mkdir(exist_ok=True)

Hier ist der relevante Teil der pathlib.Path.mkdir :

Wenn exist_ok true exist_ok ist, werden FileExistsError Ausnahmen ignoriert (dasselbe Verhalten wie der POSIX mkdir -p Befehl POSIX mkdir -p ), jedoch nur, wenn die letzte Pfadkomponente keine vorhandene Nichtverzeichnisdatei ist.

Hier ist ein bisschen mehr vom Skript - in meinem Fall bin ich nicht an eine Race-Bedingung gebunden. Ich habe nur einen Prozess, der erwartet, dass das Verzeichnis (oder die enthaltenen Dateien) vorhanden sind, und ich habe nichts zu entfernen versucht das Verzeichnis.

todays_file = directory / str(datetime.datetime.utcnow().date())
if todays_file.exists():
    logger.info("todays_file exists: " + str(todays_file))
    df = pd.read_json(str(todays_file))

Pfadobjekte müssen in str erzwungen werden, bevor andere APIs, die str Pfade erwarten, sie verwenden können.

Möglicherweise sollten Pandas aktualisiert werden, um Instanzen der abstrakten Basisklasse os.PathLike zu akzeptieren.


Python 3.5+:

import pathlib
pathlib.Path('/my/directory').mkdir(parents=True, exist_ok=True) 

pathlib.Path.mkdir wie oben verwendet, erstellt das Verzeichnis rekursiv und löst keine Ausnahme aus, wenn das Verzeichnis bereits vorhanden ist. Wenn Sie nicht möchten, dass die Eltern erstellt werden, überspringen Sie das Argument der parents .

Python 3.2+:

pathlib :

Wenn möglich, installieren Sie den aktuellen pathlib Backport namens pathlib2 . Installieren Sie nicht den älteren, nicht gepflegten Rückport namens pathlib . Lesen Sie als Nächstes den Abschnitt über Python 3.5+ und verwenden Sie ihn gleich.

Wenn Sie Python 3.4 verwenden, fehlt die nützliche Option pathlib , obwohl sie mit pathlib exist_ok . Der Backport soll eine neuere und mkdir Implementierung von mkdir die diese fehlende Option beinhaltet.

Mit os :

import os
os.makedirs(path, exist_ok=True)

os.makedirs wie oben verwendet erstellt das Verzeichnis rekursiv und löst keine Ausnahme aus, wenn das Verzeichnis bereits vorhanden ist. Es hat nur das optionale Argument exist_ok, wenn Python 3.2+ verwendet wird, mit einem Standardwert von False . Dieses Argument existiert in Python 2.x bis 2.7 nicht. Daher ist keine manuelle Ausnahmebehandlung wie bei Python 2.7 erforderlich.

Python 2.7+:

pathlib :

Wenn möglich, installieren Sie den aktuellen pathlib Backport namens pathlib2 . Installieren Sie nicht den älteren, nicht gepflegten Rückport namens pathlib . Lesen Sie als Nächstes den Abschnitt über Python 3.5+ und verwenden Sie ihn gleich.

Mit os :

import os
try: 
    os.makedirs(path)
except OSError:
    if not os.path.isdir(path):
        raise

Während eine naive Lösung zuerst os.path.isdir gefolgt von os.makedirs , kehrt die obige Lösung die Reihenfolge der beiden Vorgänge um. Auf diese Weise wird verhindert, dass eine häufige Racebedingung einen doppelten Versuch zur Erstellung des Verzeichnisses verursacht, und dass auch Dateien von Verzeichnissen unterschieden werden.

Beachten Sie, dass das Erfassen der Ausnahme und die Verwendung von errno von begrenztem Nutzen sind, da OSError: [Errno 17] File exists , dh errno.EEXIST wird sowohl für Dateien als auch für Verzeichnisse errno.EEXIST . Es ist zuverlässiger, einfach zu prüfen, ob das Verzeichnis existiert.

Alternative:

mkpath erstellt das verschachtelte Verzeichnis und führt nichts aus, wenn das Verzeichnis bereits vorhanden ist. Dies funktioniert in Python 2 und 3.

import distutils.dir_util
distutils.dir_util.mkpath(path)

Per Bug 10948 besteht eine gravierende Einschränkung dieser Alternative darin, dass sie nur einmal pro Python-Prozess für einen bestimmten Pfad funktioniert. Wenn Sie es also zum Erstellen eines Verzeichnisses verwenden, das Verzeichnis dann innerhalb oder außerhalb von Python löschen und das Verzeichnis erneut mit mkpath erneut erstellen, verwendet mkpath die ungültigen zwischengespeicherten Informationen, indem es das Verzeichnis zuvor erstellt hat, und macht das Verzeichnis eigentlich nicht nochmal. Im Gegensatz dazu ist os.makedirs auf keinen solchen Cache angewiesen. Diese Einschränkung kann für einige Anwendungen in Ordnung sein.

Bezüglich des Modus des Verzeichnisses beziehen Sie sich bitte auf die Dokumentation, wenn Sie sich darum kümmern.


Um nur die Version os.stat (Python 2) zur Verfügung zu stellen:

import os, stat, errno
def CheckIsDir(directory):
  try:
    return stat.S_ISDIR(os.stat(directory).st_mode)
  except OSError, e:
    if e.errno == errno.ENOENT:
      return False
    raise




python exception path directory operating-system