Gibt es eine Möglichkeit, eine ähnliche Funktionalität zu erhalten wie mkdir -p
auf der Shell aus Python heraus. Ich bin auf der Suche nach einer anderen Lösung als einem Systemaufruf. Ich bin sicher, der Code ist weniger als 20 Zeilen, und ich frage mich, ob jemand es bereits geschrieben hat?
- Wie kann ich ein verschachteltes Verzeichnis sicher erstellen? (30 Antworten )
Antworten
Zu viele Anzeigen?mkdir -p
gibt eine Fehlermeldung aus, wenn die Datei bereits existiert:
$ touch /tmp/foo
$ mkdir -p /tmp/foo
mkdir: cannot create directory `/tmp/foo': File exists
Eine Verfeinerung der vorangegangenen Vorschläge wäre es also, die raise
die Ausnahme, wenn os.path.isdir
gibt zurück. False
(bei der Prüfung auf errno.EEXIST
).
(Update) Siehe auch dies sehr ähnliche Frage Ich stimme mit der akzeptierten Antwort (und den Vorbehalten) überein, würde aber empfehlen os.path.isdir
代わりに os.path.exists
.
(Update) Nach 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)
Wie in den anderen Lösungen erwähnt, wollen wir in der Lage sein, das Dateisystem einmal zu treffen, während wir das Verhalten von mkdir -p
. Ich glaube nicht, dass dies möglich ist, aber wir sollten uns so weit wie möglich annähern.
Erst der Code, dann die Erklärung:
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 zu @tzots Antwort 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 sagen, ob jemand das Dateisystem in der Zwischenzeit geändert hat. Das passt auch zu Pythons Stil, nach Vergebung zu fragen, nicht nach Erlaubnis.
Wir sollten also zunächst versuchen, das Verzeichnis zu erstellen, und dann, wenn es schief geht, herausfinden, warum.
Jacob Gabrielson weist darauf hin, dass einer der Fälle, auf die wir achten müssen, der ist, dass an der Stelle, an der wir das Verzeichnis anlegen wollen, bereits eine Datei existiert.
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.
Wir müssen also herausfinden, ob dies der Fall war. Leider können wir das nicht. Wir erhalten dieselbe Fehlermeldung von makedirs zurück, unabhängig davon, ob ein Verzeichnis existiert (gut) oder 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 es dort ein Verzeichnis gibt. 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 in einem anderen Zustand befinden kann als zum Zeitpunkt des Aufrufs von makedirs. z.B.: es gab eine Datei, die makedirs zum Scheitern brachte, aber jetzt ist ein Verzeichnis an ihrer Stelle. Das macht aber nicht viel aus, da die Funktion nur dann stillschweigend beendet wird, ohne eine Exception auszulösen, wenn zum Zeitpunkt des letzten Dateisystemaufrufs das Verzeichnis existierte.
Ich denke, Asas Antwort ist im Wesentlichen richtig, aber man könnte sie ein wenig erweitern, so dass sie mehr wie mkdir -p
entweder:
import os
def mkdir_path(path):
if not os.access(path, os.F_OK):
os.mkdirs(path)
oder
import os
import errno
def mkdir_path(path):
try:
os.mkdirs(path)
except os.error, e:
if e.errno != errno.EEXIST:
raise
Beide behandeln den Fall, dass der Pfad bereits existiert, lassen aber andere Fehler auftauchen.
Funktionserklärung;
import os
def mkdir_p(filename):
try:
folder=os.path.dirname(filename)
if not os.path.exists(folder):
os.makedirs(folder)
return True
except:
return False
Verwendung:
filename = "./download/80c16ee665c8/upload/backup/mysql/2014-12-22/adclient_sql_2014-12-22-13-38.sql.gz"
if (mkdir_p(filename):
print "Created dir :%s" % (os.path.dirname(filename))
0 Stimmen
Wie erreicht man die Entsprechung von "mkdir -p /home/Dokumente/Ordner/{Unterordner1,Unterordner2}" in os.command? Es erstellt einen Ordner als {Unterordner1,Unterordner2} anstelle von 2 verschiedenen Ordnern
0 Stimmen
Was ist der Unterschied zwischen makedirs und mkdir von os?