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.
Wie erstelle ich ein Verzeichnis und alle fehlenden übergeordneten Verzeichnisse?
Teil
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.exists
und ü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.exists
aber 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ückTrue
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 zuos.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 benutztos.mkdir()
Diese Fehler lösen eine Ausnahme aus und machen Sie auf ihre Existenz aufmerksam.– Dreviko
6. Juli 2013 um 6:41 Uhr
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 pathlib
es 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 exists
dh 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
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
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()
.
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
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
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
p
hier ist mein Codeschnipsel:os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
– Thamme Gowda
25. Oktober 2016 um 3:40 Uhr