mkdir -p Funktionalität in Python [Duplikat]
Frage
Diese Frage bereits eine Antwort hier:
Gibt es einen Weg, um eine ähnliche Funktionalität wie aus Python auf der Schale mkdir -p
. Ich bin auf der Suche nach einer Lösung anderes als ein Systemaufruf. Ich bin sicher, dass der Code weniger als 20 Zeilen sind, und ich frage mich, wenn jemand hat es schon geschrieben?
Lösung
mkdir -p
Funktionalität wie folgt:
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
else:
raise
Update
Für Python ≥ 3.2, hat os.makedirs
eine Argument exist_ok
die, wenn sie wahr ist, die mkdir -p
Funktionalität ermöglicht - es sei denn, mode
vorgesehen ist und das bestehende Verzeichnis unterschiedliche Berechtigungen als die beabsichtigten diejenigen hat; in diesem Fall OSError
wie zuvor erhöht.
Update 2
Für Python ≥ 3,5, gibt es auch 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 hinzugefügt 3.5.
Andere Tipps
In Python> = 3.2, das ist
os.makedirs(path, exist_ok=True)
In früheren Versionen verwenden @ tzot Antwort .
Das ist einfacher als die Ausnahme Trapping:
import os
if not os.path.exists(...):
os.makedirs(...)
Hinweis Dieser Ansatz erfordert zwei Systemaufrufe, die anfälliger ist Bedingungen unter bestimmten Umgebungen / Bedingungen zu fahren. Wenn Sie sich etwas komplizierter als ein einfacher Wegwerf-Skript ausgeführt wird in einer kontrollierten Umgebung zu schreiben, sind Sie besser dran mit der akzeptierten Antwort gehen, dass nur einen Systemaufruf erfordert.
UPDATE 2012-07-27
ich diese Antwort zu löschen versucht, aber ich denke, es ist Wert im Kommentarthread unten. Als solche Umwandlung ich es zu einem Wiki.
Vor kurzem fand ich diese distutils.dir_util.mkpath :
In [17]: from distutils.dir_util import mkpath
In [18]: mkpath('./foo/bar')
Out[18]: ['foo', 'foo/bar']
mkdir -p
gibt einen Fehler, wenn die Datei bereits vorhanden ist:
$ touch /tmp/foo
$ mkdir -p /tmp/foo
mkdir: cannot create directory `/tmp/foo': File exists
So eine Verfeinerung der vorherigen Vorschläge wäre die Ausnahme erneut raise
wenn os.path.isdir
kehrt False
(wenn für errno.EEXIST
Überprüfung).
(Update) Siehe auch diese sehr ähnliche Frage ; Ich stimme mit der akzeptierten Antwort (und Einschränkungen), außer ich os.path.isdir
statt os.path.exists
empfehlen würde.
(Update) pro Anregung in den Kommentaren, würde die volle Funktion wie folgt aussehen:
import os
def mkdirp(directory):
if not os.path.isdir(directory):
os.makedirs(directory)
Wie bei den anderen Lösungen erwähnt, wollen wir in der Lage sein, sobald das Dateisystem zu schlagen, während das Verhalten von mkdir -p
nachahmt. Ich glaube nicht, dass dies möglich ist zu tun, aber wir sollten so nah wie möglich erhalten.
-Code zunächst Erklärung später:
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 @ tzot Antwort zeigt, gibt es Probleme mit der Überprüfung, ob Sie ein Verzeichnis erstellen können, bevor Sie es tatsächlich schaffen: man kann nicht sagen, ob jemand das Dateisystem in der Zwischenzeit verändert hat. Das paßt auch mit Python-Stil um Vergebung zu bitten, nicht die Erlaubnis.
Das erste, was wir tun sollen, ist versuchen, das Verzeichnis zu machen, dann, wenn es schief geht, herauszufinden, warum.
Wie Jacob Gabrielson weist darauf hin, einer der Fälle, die wir für den Fall aussehen muss, wenn eine Datei bereits vorhanden ist, wo wir das Verzeichnis zu setzen versuchen.
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 eine Ausnahme zu machen.
Also müssen wir arbeiten, wenn dies der Fall ist. Leider können wir nicht. Wir erhalten die gleiche Fehlermeldung zurück von makedirs, ob ein Verzeichnis vorhanden ist (gut) oder eine Datei existiert die Erstellung des Verzeichnisses zu verhindern (sehr schlecht).
Der einzige Weg, um herauszufinden, was passiert ist wieder das Dateisystem zu untersuchen, um zu sehen, ob es ein Verzeichnis gibt. Wenn ja, dann leise zurückkehren, da sonst die Ausnahme ausgelöst.
Das einzige Problem ist, dass das Dateisystem in einem anderen Zustand sein kann, jetzt, als wenn makedirs genannt wurde. zB: eine Datei existiert verursacht makedirs zum Scheitern verurteilt, aber jetzt ein Verzeichnis ist an seinem Platz. Das ist nicht wirklich wichtig, dass viel, weil die die Funktion nur leise verlassen, ohne eine Ausnahme zu erhöhen, wenn zum Zeitpunkt der letzten Dateisystem nennen das Verzeichnis existiert.
Mit Pathlib von python3 Standardbibliothek:
Path(mypath).mkdir(parents=True, exist_ok=True)
Wenn Eltern wahr ist, alle fehlenden Eltern dieses Weges geschaffen als erforderlich; sie werden mit den Standardberechtigungen erstellt, ohne dabei Modus berücksichtigt (der POSIX mkdir -p Befehl nachahmt). Wenn exist_ok falsch ist (Standardeinstellung), wird ein FileExistsError ausgelöst, wenn das Zielverzeichnis bereits vorhanden ist.
Wenn exist_ok wahr ist, FileExistsError Ausnahmen werden ignoriert (gleiche Verhalten wie der -p Befehl mkdir POSIX), aber nur, wenn der letzte Weg Komponente ist nicht eine bestehende nicht-Verzeichnisdatei.
Changed in Version 3.5:. Der exist_ok Parameter wurde hinzugefügt
ich glaube, Asa Antwort im Wesentlichen richtig ist, aber man konnte erweitert es ein wenig mehr wie mkdir -p
zu handeln, 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
Diese sowohl den Fall behandeln, wo der Weg schweigend bereits vorhanden ist, aber andere Fehler sprudeln lassen.
Funktionsdeklaration;
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
Nutzung:
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))
Ich habe Erfolg gehabt mit persönlich dem folgenden, aber meine Funktion soll wohl so etwas wie ‚gewährleistet dieses Verzeichnis existiert‘ aufgerufen werden:
def mkdirRecursive(dirpath):
import os
if os.path.isdir(dirpath): return
h,t = os.path.split(dirpath) # head/tail
if not os.path.isdir(h):
mkdirRecursive(h)
os.mkdir(join(h,t))
# end mkdirRecursive
import os
import tempfile
path = tempfile.mktemp(dir=path)
os.makedirs(path)
os.rmdir(path)
import os
from os.path import join as join_paths
def mk_dir_recursive(dir_path):
if os.path.isdir(dir_path):
return
h, t = os.path.split(dir_path) # head/tail
if not os.path.isdir(h):
mk_dir_recursive(h)
new_path = join_paths(h, t)
if not os.path.isdir(new_path):
os.mkdir(new_path)
basierend auf @ Dave C Antwort, aber mit einem Fehler behoben, wo ein Teil des Baumes ist bereits vorhanden