Wie erstelle ich ein Verzeichnis und alle fehlenden übergeordneten Verzeichnisse?

Lesezeit: 10 Minuten

Benutzeravatar von Parand
Teil

Wie erstelle ich ein Verzeichnis unter einem bestimmten Pfad und erstelle auch alle fehlenden übergeordneten Verzeichnisse entlang dieses Pfads? Zum Beispiel der Bash-Befehl mkdir -p /path/to/nested/directory macht dies.

  • Im Allgemeinen müssen Sie möglicherweise den Fall berücksichtigen, in dem der Dateiname kein Verzeichnis enthält. Auf meinem Rechner ergibt dirname(‘foo.txt’) ”, das nicht existiert und dazu führt, dass makedirs() fehlschlägt.

    – Brian Hawkins

    26. Mai 2010 um 23:30 Uhr

  • Wenn der Pfad existiert, muss nicht nur überprüft werden, ob es sich um ein Verzeichnis und nicht um eine normale Datei oder ein anderes Objekt handelt (viele Antworten überprüfen dies), sondern es muss auch überprüft werden, ob er beschreibbar ist (ich habe keine Antwort gefunden, die dies überprüft hat).

    – Wunder173

    19. Februar 2014 um 19:52 Uhr

  • Falls Sie hierher gekommen sind, um übergeordnete Verzeichnisse der Dateipfadzeichenfolge zu erstellen phier ist mein Codeschnipsel: os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)

    – Thamme Gowda

    25. Oktober 2016 um 3:40 Uhr

Benutzeravatar von Blair Conrad
Blair Konrad

Verwenden Sie bei Python ≥ 3.5 pathlib.Path.mkdir:

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

Für ältere Versionen von Python sehe ich zwei Antworten mit guten Eigenschaften, jede mit einem kleinen Fehler, also werde ich meine Meinung dazu sagen:

Versuchen os.path.existsund überlegen os.makedirs für die Schöpfung.

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

Wie in den Kommentaren und an anderer Stelle erwähnt, gibt es eine Race-Bedingung – wenn das Verzeichnis zwischen dem erstellt wird os.path.exists und das os.makedirs Anrufe, die os.makedirs wird mit einem scheitern OSError. Leider Deckenfang OSError und das Fortsetzen ist nicht narrensicher, da es einen Fehler beim Erstellen des Verzeichnisses aufgrund anderer Faktoren wie unzureichende Berechtigungen, volle Festplatte usw. ignoriert.

Eine Möglichkeit wäre, die abzufangen OSError und untersuchen Sie den eingebetteten Fehlercode (siehe Gibt es eine plattformübergreifende Möglichkeit, 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 noch eine zweite geben os.path.existsaber angenommen, ein anderer hat das Verzeichnis nach der ersten Überprüfung erstellt und es dann vor der zweiten entfernt – wir könnten uns immer noch täuschen lassen.

Je nach Anwendung kann die Gefahr von gleichzeitigen Operationen größer oder geringer sein als die Gefahr, die von anderen Faktoren wie Dateiberechtigungen ausgeht. Der Entwickler müsste mehr über die spezielle zu entwickelnde Anwendung und ihre erwartete Umgebung wissen, bevor er eine Implementierung auswählt.

Moderne Versionen von Python verbessern diesen Code erheblich, beides durch Offenlegung FileExistsError (in 3.3+)…

try:
    os.makedirs("path/to/directory")
except FileExistsError:
    # directory already exists
    pass

…und durch Zulassen ein Schlüsselwortargument zu os.makedirs genannt exist_ok (in 3.2+).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.

  • Die Racebedingung ist ein guter Punkt, aber der Ansatz in stackoverflow.com/questions/273192/#273208 verschleiert einen Fehler beim Erstellen des Verzeichnisses. Fühlen Sie sich nicht schlecht, wenn Sie abgelehnt haben – Ihnen gefällt die Antwort nicht. Dafür sind Stimmen da.

    – Blair Conrad

    7. November 2008 um 20:35 Uhr

  • Denken Sie daran, dass os.path.exists() nicht kostenlos ist. Wenn der Normalfall darin besteht, dass das Verzeichnis vorhanden sein wird, sollte der Fall, in dem dies nicht der Fall ist, als Ausnahme behandelt werden. Mit anderen Worten, versuchen Sie, Ihre Datei zu öffnen und in sie zu schreiben, fangen Sie die OSError-Ausnahme ab und führen Sie auf der Grundlage von errno Ihr makedir() aus und versuchen Sie es erneut oder erhöhen Sie erneut. Dadurch wird Code dupliziert, es sei denn, Sie packen das Schreiben in eine lokale Methode.

    – Andreas

    28. November 2011 um 19:10 Uhr


  • os.path.exists kehrt auch zurück True für eine Datei. Ich habe eine Antwort gepostet, um darauf einzugehen.

    – Asklepios

    14. Februar 2013 um 17:32 Uhr

  • Wie Kommentatoren zu anderen Antworten hier bemerkt haben, ist die exists_ok Parameter zu os.makedirs() kann verwendet werden, um abzudecken, wie die vorherige Existenz des Pfads gehandhabt wird, da Python 3.2.

    – Bommel

    20. Mai 2013 um 6:50 Uhr

  • os.mkdirs() kann unbeabsichtigte Ordner erstellen, wenn versehentlich ein Pfadtrennzeichen weggelassen wird, der aktuelle Ordner nicht wie erwartet ist, ein Pfadelement das Pfadtrennzeichen enthält. Wenn du benutzt os.mkdir() Diese Fehler lösen eine Ausnahme aus und machen Sie auf ihre Existenz aufmerksam.

    – Dreviko

    6. Juli 2013 um 6:41 Uhr

Benutzeravatar von Asclepius
Asklepios

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 die übergeordneten Elemente nicht erstellen müssen oder möchten, überspringen Sie die parents Streit.

Python 3.2+:

Verwenden pathlib:

Wenn möglich, installiere die aktuelle pathlib Backport benannt pathlib2. Installieren Sie nicht den älteren, nicht gewarteten Backport namens pathlib. Als nächstes lesen Sie den Abschnitt Python 3.5+ oben und verwenden Sie ihn genauso.

Wenn Sie Python 3.4 verwenden, obwohl es mitgeliefert wird pathlibes fehlt das Nützliche exist_ok Möglichkeit. Der Backport soll eine neuere und bessere Implementierung von bieten mkdir die diese fehlende Option enthält.

Verwenden 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 die Option exist_ok Argument nur bei Verwendung von Python 3.2+, 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+:

Verwenden pathlib:

Wenn möglich, installiere die aktuelle pathlib Backport benannt pathlib2. Installieren Sie nicht den älteren, nicht gewarteten Backport namens pathlib. Als nächstes lesen Sie den Abschnitt Python 3.5+ oben und verwenden Sie ihn genauso.

Verwenden os:

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

Während eine naive Lösung zunächst verwendet werden kann os.path.isdir gefolgt von os.makedirs, kehrt die obige Lösung die Reihenfolge der beiden Operationen um. Dadurch verhindert es eine häufige Racebedingung, die mit einem doppelten Versuch beim Erstellen des Verzeichnisses zu tun hat, und macht auch Dateien aus Verzeichnissen eindeutig.

Beachten Sie, dass das Erfassen der Ausnahme und die Verwendung von errno ist von begrenztem Nutzen, weil OSError: [Errno 17] File existsdh errno.EEXIST, wird sowohl für Dateien als auch für Verzeichnisse ausgelöst. Zuverlässiger ist es, einfach zu prüfen, ob das Verzeichnis existiert.

Alternative:

mkpath erstellt das verschachtelte Verzeichnis und tut nichts, wenn das Verzeichnis bereits vorhanden ist. Dies funktioniert sowohl in Python 2 als auch in Python 3. Beachten Sie jedoch Folgendes distutils ist veraltet und soll in Python 3.12 entfernt werden.

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

Pro Fehler 10948, besteht eine schwerwiegende Einschränkung dieser Alternative darin, dass sie nur einmal pro Python-Prozess für einen bestimmten Pfad funktioniert. Mit anderen Worten, wenn Sie es zum Erstellen eines Verzeichnisses verwenden, löschen Sie das Verzeichnis innerhalb oder außerhalb von Python und verwenden Sie dann mkpath erneut, um dasselbe Verzeichnis neu zu erstellen, mkpath verwendet einfach stillschweigend seine ungültigen zwischengespeicherten Informationen darüber, dass das Verzeichnis zuvor erstellt wurde, und erstellt das Verzeichnis nicht wirklich erneut. Im Gegensatz, os.makedirs verlässt sich nicht auf einen solchen Cache. Diese Einschränkung kann für einige Anwendungen in Ordnung sein.


In Bezug auf das Verzeichnis Moduslesen Sie bitte die Dokumentation, wenn Sie sich darum kümmern.

  • Diese Antwort deckt so ziemlich jeden Sonderfall ab, soweit ich das beurteilen kann. Ich plane jedoch, dies in ein “if not os.path.isdir()” zu packen, da ich erwarte, dass das Verzeichnis fast jedes Mal existiert und ich die Ausnahme auf diese Weise vermeiden kann.

    – Karl L.

    26. April 2013 um 5:52 Uhr


  • @CharlesL. Eine Ausnahme ist wahrscheinlich billiger als das Disk-IO des Checks, wenn Ihr Grund die Leistung ist.

    – jpmc26

    29. April 2014 um 22:39 Uhr


  • @ jpmc26 aber makedirs führt zusätzliche Statistik, umask, lstat aus, wenn nur geprüft wird, ob OSError ausgelöst werden soll.

    – kwarunek

    19. September 2014 um 10:31 Uhr


  • Dies ist die falsche Antwort, da sie eine potenzielle FS-Rennbedingung einführt. Siehe Antwort von Aaron Hall.

    – SleepyCal

    8. Januar 2016 um 15:20 Uhr

  • Wie @sleepycal gesagt hat, leidet dies unter einer ähnlichen Rennbedingung wie die akzeptierte Antwort. Wenn zwischen dem Auslösen des Fehlers und dem Überprüfen os.path.isdir jemand anderes den Ordner löscht, werden Sie den falschen, veralteten und verwirrenden Fehler auslösen, dass der Ordner existiert.

    – Bauer

    27. April 2016 um 7:20 Uhr

Benutzeravatar von Heikki Toivonen
Heikki Toivonen

Die Verwendung von try except und dem richtigen Fehlercode aus dem errno-Modul beseitigt die Race-Condition und ist plattformübergreifend:

import os
import errno

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

Mit anderen Worten, wir versuchen, die Verzeichnisse zu erstellen, aber wenn sie bereits existieren, ignorieren wir den Fehler. Andererseits wird jeder andere Fehler gemeldet. Wenn Sie beispielsweise zuvor Verzeichnis ‘a’ erstellen und alle Berechtigungen daraus entfernen, erhalten Sie eine OSError mit aufgezogen errno.EACCES (Erlaubnis verweigert, Fehler 13).

  • Die akzeptierte Antwort ist tatsächlich gefährlich, weil sie eine Race-Condition hat. Es ist jedoch einfacher. Wenn Sie also die Rennbedingungen nicht kennen oder glauben, dass sie nicht auf Sie zutreffen, wäre dies Ihre offensichtliche erste Wahl.

    – Heikki Toivonen

    7. Mai 2012 um 18:23 Uhr

  • Auslösen der Ausnahme nur wenn exception.errno != errno.EEXIST wird unbeabsichtigt den Fall ignorieren, wenn der Pfad existiert, aber ein Nicht-Verzeichnisobjekt wie eine Datei ist. Die Ausnahme sollte idealerweise ausgelöst werden, wenn der Pfad kein Verzeichnisobjekt ist.

    – Asklepios

    16. Januar 2013 um 17:13 Uhr

  • Beachten Sie, dass der obige Code äquivalent zu ist os.makedirs(path,exist_ok=True)

    – Navin

    9. Februar 2013 um 15:36 Uhr

  • @Navin Der exist_ok -Parameter wurde in Python 3.2 eingeführt. Es ist in Python 2.x nicht vorhanden. Ich werde es in meine Antwort einfließen lassen.

    – Asklepios

    14. Februar 2013 um 17:46 Uhr

  • @HeikkiToivonen Technisch gesehen, wenn ein anderes Programm die Verzeichnisse und Dateien gleichzeitig mit Ihrem Programm ändert, ist Ihr gesamtes Programm eine riesige Wettlaufbedingung. Was hindert ein anderes Programm daran, dieses Verzeichnis einfach zu löschen, nachdem der Code es erstellt hat und bevor Sie tatsächlich Dateien darin ablegen?

    – jpmc26

    29. April 2014 um 22:41 Uhr


Benutzeravatar des hiro-Protagonisten
Hiro-Protagonist

Ab Python 3.5, pathlib.Path.mkdir hat ein exist_ok Flagge:

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.

(genauso wie os.makedirs bekam ein exist_ok Flag ab Python 3.2 zB os.makedirs(path, exist_ok=True))


Hinweis: Als ich diese Antwort gepostet habe, wurde keine der anderen Antworten erwähnt exist_ok

Ich persönlich würde Ihnen die Verwendung empfehlen os.path.isdir() statt zu testen os.path.exists().

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

>>> directory = raw_input(":: ")

Und eine dumme Benutzereingabe:

:: /tmp/dirname/filename.etc

… Sie werden mit einem Verzeichnis namens enden filename.etc wenn Sie dieses Argument übergeben os.makedirs() wenn du mit testest os.path.exists().

Benutzeravatar von Georgy
Georgi

Überprüfen os.makedirs: (Es stellt sicher, dass der vollständige Pfad vorhanden ist.)
Um mit der Tatsache umzugehen, dass das Verzeichnis möglicherweise existiert, catch OSError. (Wenn exist_ok Ist False (Standard), ein OSError wird ausgelöst, wenn das Zielverzeichnis bereits existiert.)

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

Benutzeravatar von jesterjunk
Spaßvogel

Versuchen Sie die os.path.exists Funktion

if not os.path.exists(dir):
    os.mkdir(dir)

  • Dadurch werden keine übergeordneten Verzeichnisse erstellt. Von dem os.mkdir Dokumente: “Wenn kein übergeordnetes Verzeichnis im Pfad vorhanden ist, FileNotFoundError wird erhoben.”

    –Ryan M

    Vor 2 Tagen

1450090cookie-checkWie erstelle ich ein Verzeichnis und alle fehlenden übergeordneten Verzeichnisse?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy