Gibt es eine Möglichkeit, ähnliche Funktionen wie mkdir -p
auf der Shell aus Python heraus. Ich suche nach einer anderen Lösung als einem Systemaufruf. Ich bin mir sicher, dass der Code weniger als 20 Zeilen umfasst, und ich frage mich, ob ihn schon jemand geschrieben hat?
mkdir -p-Funktionalität in Python [duplicate]
Setjmp
tzot
Verwenden Sie für Python ≥ 3.5 pathlib.Path.mkdir
:
import pathlib
pathlib.Path("/tmp/path/to/desired/directory").mkdir(parents=True, exist_ok=True)
Der exist_ok
-Parameter wurde in Python 3.5 hinzugefügt.
Für Python ≥ 3.2, os.makedirs
hat ein optionales drittes Argument exist_ok
das, wann True
ermöglicht die mkdir -p
Funktionalität—es sei denn mode
bereitgestellt wird und das vorhandene Verzeichnis andere Berechtigungen als die beabsichtigten hat; In diesem Fall, OSError
wird wie bisher angehoben:
import os
os.makedirs("/tmp/path/to/desired/directory", exist_ok=True)
Für noch ältere Versionen von Python können Sie verwenden os.makedirs
und ignoriere den Fehler:
import errno
import os
def mkdir_p(path):
try:
os.makedirs(path)
except OSError as exc: # Python ≥ 2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
# possibly handle other errno cases here, otherwise finally:
else:
raise
-
Im Geiste der Mikroverbesserung werden viele Leute kopieren und einfügen: Wie wäre es mit dem Ersetzen?
==
mit!=
und Entfernen derpass
/else
🙂– Will Hardy
4. August 11 um 15:51 Uhr
-
Dies scheint fehlzuschlagen, wenn der letzte Teil des Pfads eine Datei ist, da exc.errno gleich errno.EEXIST ist und daher alles in Ordnung zu sein scheint, aber die tatsächliche Verwendung des Verzeichnisses später fehlschlägt.
– elfe
7. November 12 um 1:53 Uhr
-
Wie wäre es mit distutils.dir_util.mkpath? Es ist ziemlich einfach
mkpath('./foo/bar')
– auraham
15. Januar 13 um 21:41 Uhr
-
Ausnahmebehandlung optimieren? außer OSError als exc: if exc.errno != errno.EEXIST oder nicht os.path.isdir(path): raise
– Julian
4. Februar 14 um 21:23 Uhr
-
@auraham, mkpath hat ein unerwartetes Verhalten aufgrund von undokumentiertem Caching, das Probleme verursachen kann, wenn Sie versuchen, es genau wie mkdir -p zu verwenden: bugs.python.org/issue10948.
– romanows
18. Februar 15 um 3:00 Uhr
Fred Fu
In Python >=3.2 ist das
os.makedirs(path, exist_ok=True)
Verwenden Sie in früheren Versionen die Antwort von @tzot.
Dies ist einfacher als das Abfangen der Ausnahme:
import os
if not os.path.exists(...):
os.makedirs(...)
Haftungsausschluss Dieser Ansatz erfordert zwei Systemaufrufe, was unter bestimmten Umgebungen/Bedingungen anfälliger für Wettlaufbedingungen ist. Wenn Sie etwas Anspruchsvolleres schreiben als ein einfaches Wegwerfskript, das in einer kontrollierten Umgebung ausgeführt wird, sollten Sie besser die akzeptierte Antwort verwenden, die nur einen Systemaufruf erfordert.
UPDATE 2012-07-27
Ich bin versucht, diese Antwort zu löschen, aber ich denke, der Kommentarthread unten hat einen Wert. Als solches wandle ich es in ein Wiki um.
-
Auf diese Weise machen Sie es weniger wahrscheinlich, aber nicht unmöglich, dass Makedirs in allen Multitasking-Betriebssystemen fehlschlagen. Es ist wie zu sagen “256 Zeichen sollten für jeden erstellten Pfad ausreichen”.
– zot
2. März 09 um 23:42 Uhr
-
@Asa Natürlich. Und mkdir -p würde sich auch darüber beschweren. Habe ich deinen Punkt verpasst?
– Joe Holloway
3. März 09 um 19:15 Uhr
-
@jholloway7: Basierend auf den Anforderungen (“mkdir -p” -ähnliche Funktionalität) ist Asas Kommentar unnötig. Ich würde jedoch gerne wissen, ob Sie anerkennen, dass es möglich ist, dass das Verzeichnis nicht existiert, wenn .exists aufgerufen wird, und existiert, wenn .makedirs aufgerufen wird.
– zot
3. März 09 um 22:38 Uhr
-
@TZ Ja, das erkenne ich auf jeden Fall an. Ohne vollständige Spezifikationen aus dem Originalposter ging ich davon aus, dass er/sie eine Lösung wollte, die zum Erstellen eines Verzeichnisbaums verwendet werden kann, wenn sie nicht bereits in einem einfachen Skript vorhanden ist, und keine HA-Unternehmensproduktionslösung mit SLAs.
– Joe Holloway
4. März 09 um 15:06 Uhr
-
@Asa Dafür sind Ausnahmen da, etwas Unerwartetes ist schief gelaufen. Wenn Sie keine Berechtigungen haben, sprudelt die Ausnahme ganz nach oben und Sie bemerken, dass Sie die Berechtigungen korrigieren müssen. So wie es sein sollte.
– jpsimons
11. Juli 10 um 23:04 Uhr
Kürzlich habe ich das gefunden distutils.dir_util.mkpath:
In [17]: from distutils.dir_util import mkpath
In [18]: mkpath('./foo/bar')
Out[18]: ['foo', 'foo/bar']
Jakob Gabrielson
mkdir -p
gibt Ihnen einen Fehler, wenn die Datei bereits existiert:
$ touch /tmp/foo
$ mkdir -p /tmp/foo
mkdir: cannot create directory `/tmp/foo': File exists
Eine Verfeinerung der vorherigen Vorschläge wäre also,raise
die Ausnahme wenn os.path.isdir
kehrt zurück False
(bei der Suche nach errno.EEXIST
).
(Update) Siehe auch diese sehr ähnliche Frage; Ich stimme der akzeptierten Antwort (und Vorbehalten) zu, außer ich würde empfehlen os.path.isdir
anstatt os.path.exists
.
(Update) Gemäß einem Vorschlag in den Kommentaren würde die vollständige Funktion wie folgt aussehen:
import os
def mkdirp(directory):
if not os.path.isdir(directory):
os.makedirs(directory)
-
In diesem Fall haben Sie absolut Recht; Das Programm sollte jedoch später Ausnahmen abfangen, z. B. beim Versuch, open(“/tmp/foo/a_file”, “w”) zu öffnen, daher denke ich nicht, dass ein Update erforderlich ist. Sie könnten Ihre Antwort stattdessen mit Python-Code aktualisieren und zusehen, wie sie positiv bewertet wird;)
– zot
3. März 09 um 22:43 Uhr
-
In vielen Fällen wäre das wahrscheinlich in Ordnung. Im Allgemeinen würde ich es jedoch vorziehen, dass der Code so früh wie möglich fehlschlägt, damit klar ist, was das Problem wirklich verursacht hat.
– Jakob Gabrielson
3. März 09 um 22:47 Uhr
-
Wenn es bereits ALS VERZEICHNIS existiert, gibt mkdir -p keinen Fehler aus. Es tritt ein Fehler auf, wenn Sie es auffordern, ein Verzeichnis zu erstellen, und eine DATEI mit diesem Namen bereits vorhanden ist.
– Frank Klotz
6. Dezember 12 um 18:49 Uhr
-
@FrankKlotz deshalb nenne ich os.path.isdir nicht os.path.exists
– Jakob Gabrielson
6. Dezember 12 um 23:45 Uhr
-
−1, weil der einzige Teil dieser Antwort, der die Frage tatsächlich beantwortet (der letzte Codeblock), sie falsch beantwortet und auch andere Antworten dupliziert.
– Waschen
4. Februar 19 um 21:50 Uhr
Antony Hatchkin
Mit Pathib aus der Python3-Standardbibliothek:
Path(mypath).mkdir(parents=True, exist_ok=True)
Wenn parent wahr ist, werden alle fehlenden übergeordneten Elemente dieses Pfads nach Bedarf erstellt; Sie werden mit den Standardberechtigungen ohne Berücksichtigung des Modus erstellt (imitiert den POSIX-Befehl mkdir -p). Wenn exist_ok falsch ist (Standardeinstellung), wird ein FileExistsError ausgelöst, wenn das Zielverzeichnis bereits existiert.
Wenn exist_ok wahr ist, werden FileExistsError-Ausnahmen ignoriert (gleiches Verhalten wie beim POSIX-Befehl mkdir -p), aber nur, wenn die letzte Pfadkomponente keine vorhandene Nicht-Verzeichnisdatei ist.
Geändert in Version 3.5: Der Parameter exist_ok wurde hinzugefügt.
-
In diesem Fall haben Sie absolut Recht; Das Programm sollte jedoch später Ausnahmen abfangen, z. B. beim Versuch, open(“/tmp/foo/a_file”, “w”) zu öffnen, daher denke ich nicht, dass ein Update erforderlich ist. Sie könnten Ihre Antwort stattdessen mit Python-Code aktualisieren und zusehen, wie sie positiv bewertet wird;)
– zot
3. März 09 um 22:43 Uhr
-
In vielen Fällen wäre das wahrscheinlich in Ordnung. Im Allgemeinen würde ich es jedoch vorziehen, dass der Code so früh wie möglich fehlschlägt, damit klar ist, was das Problem wirklich verursacht hat.
– Jakob Gabrielson
3. März 09 um 22:47 Uhr
-
Wenn es bereits ALS VERZEICHNIS existiert, gibt mkdir -p keinen Fehler aus. Es tritt ein Fehler auf, wenn Sie es auffordern, ein Verzeichnis zu erstellen, und eine DATEI mit diesem Namen bereits vorhanden ist.
– Frank Klotz
6. Dezember 12 um 18:49 Uhr
-
@FrankKlotz deshalb nenne ich os.path.isdir nicht os.path.exists
– Jakob Gabrielson
6. Dezember 12 um 23:45 Uhr
-
−1, weil der einzige Teil dieser Antwort, der die Frage tatsächlich beantwortet (der letzte Codeblock), sie falsch beantwortet und auch andere Antworten dupliziert.
– Waschen
4. Februar 19 um 21:50 Uhr
c4m3lo
Wie in den anderen Lösungen erwähnt, möchten wir in der Lage sein, das Dateisystem einmal zu treffen, während wir das Verhalten von nachahmen mkdir -p
. Ich glaube nicht, dass das möglich ist, aber wir sollten so nah wie möglich herankommen.
Erst codieren, später erklären:
import os
import errno
def mkdir_p(path):
""" 'mkdir -p' in Python """
try:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else:
raise
Wie die Kommentare zur Antwort von @tzot zeigen, gibt es Probleme mit der Überprüfung, ob Sie ein Verzeichnis erstellen können, bevor Sie es tatsächlich erstellen: Sie können nicht feststellen, ob jemand das Dateisystem in der Zwischenzeit geändert hat. Das passt auch zu Pythons Stil, um Vergebung zu bitten, nicht um Erlaubnis.
Als erstes sollten wir also versuchen, das Verzeichnis zu erstellen, und wenn es schief geht, herausfinden, warum.
Wie Jacob Gabrielson betont, ist einer der Fälle, nach denen wir suchen müssen, der Fall, in dem eine Datei bereits existiert, wo wir versuchen, das Verzeichnis zu platzieren.
Mit mkdir -p
:
$ touch /tmp/foo
$ mkdir -p /tmp/foo
mkdir: cannot create directory '/tmp/foo': File exists
Das analoge Verhalten in Python wäre das Auslösen einer Ausnahme.
Also müssen wir herausfinden, ob dies der Fall war. Leider können wir nicht. Wir erhalten dieselbe Fehlermeldung von makedirs zurück, unabhängig davon, ob ein Verzeichnis existiert (gut) oder ob eine Datei existiert, die die Erstellung des Verzeichnisses verhindert (schlecht).
Die einzige Möglichkeit herauszufinden, was passiert ist, besteht darin, das Dateisystem erneut zu untersuchen, um festzustellen, ob dort ein Verzeichnis vorhanden ist. Wenn dies der Fall ist, kehren Sie stillschweigend zurück, andernfalls lösen Sie die Ausnahme aus.
Das einzige Problem ist, dass sich das Dateisystem jetzt möglicherweise in einem anderen Zustand befindet als beim Aufruf von makedirs. zB: Es existierte eine Datei, die dazu führte, dass Makedirs fehlschlugen, aber jetzt ist ein Verzeichnis an ihrer Stelle. Das ist eigentlich nicht so wichtig, da die Funktion nur dann stillschweigend beendet wird, ohne eine Ausnahme auszulösen, wenn zum Zeitpunkt des letzten Dateisystemaufrufs das Verzeichnis existierte.
-
Oder nur:
os.makedirs(path, exist_ok=True)
– Erik Aronesty
30. April 18 um 12:37 Uhr
.
Wie erreicht man “mkdir -p /home/Documents/Folder/{Subfolder1,Subfolder2}” Äquivalent in os.command ? Es erstellt einen Ordner als {Subfolder1, Subfolder2} anstelle von 2 verschiedenen Ordnern
– Akash Tyagi
9. Januar 20 um 14:25 Uhr
Was ist der Unterschied zwischen makedirs und mkdir von os?
– caot
26. März 21 um 20:17 Uhr