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?

War es hilfreich?

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top