python liste - Wie kann ich sicher ein verschachteltes Verzeichnis in Python erstellen?




13 Answers

Ich sehe zwei Antworten mit guten Qualitäten, jede mit einem kleinen Fehler, also werde ich meine Meinung dazu geben:

Probieren Sie os.path.exists und berücksichtigen Sie os.makedirs für die Erstellung.

import os
if not os.path.exists(directory):
    os.makedirs(directory)

Wie in Kommentaren und anderswo erwähnt, gibt es eine Race-Bedingung: Wenn das Verzeichnis zwischen den os.path.exists und den os.makedirs Aufrufen erstellt wird, os.makedirs die os.makedirs mit einem OSError . Unglücklicherweise ist OSError und das Fortsetzen nicht idiotensicher, da es einen Fehler beim Erstellen des Verzeichnisses aufgrund anderer Faktoren wie unzureichende Berechtigungen, volle Festplatte usw. ignoriert.

Eine Option wäre, den OSError und den eingebetteten Fehlercode zu untersuchen (siehe Gibt es eine plattformübergreifende Methode, um 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 eine zweite os.path.exists . Nehmen os.path.exists jedoch an, ein anderer os.path.exists hat das Verzeichnis nach der ersten Prüfung erstellt und dann vor der zweiten entfernt. Wir könnten uns trotzdem täuschen.

Je nach Anwendung kann die Gefahr gleichzeitiger Vorgänge mehr oder weniger als die Gefahr sein, die von anderen Faktoren wie Dateiberechtigungen ausgeht. Der Entwickler muss vor der Auswahl einer Implementierung mehr über die zu entwickelnde Anwendung und die erwartete Umgebung erfahren.

array ordner

Was ist der eleganteste Weg, um zu überprüfen, ob das Verzeichnis, in das eine Datei geschrieben werden soll, vorhanden ist, und wenn nicht, erstellen Sie das Verzeichnis mit Python? Folgendes habe ich ausprobiert:

import os

file_path = "/my/directory/filename.txt"
directory = os.path.dirname(file_path)

try:
    os.stat(directory)
except:
    os.mkdir(directory)       

f = file(filename)

Irgendwie habe ich os.path.exists vermisst (danke Kanja, Blair und Douglas). Das habe ich jetzt:

def ensure_dir(file_path):
    directory = os.path.dirname(file_path)
    if not os.path.exists(directory):
        os.makedirs(directory)

Gibt es eine Flagge für "offen", damit dies automatisch geschieht?




Mit try und und dem richtigen Fehlercode aus dem errno-Modul wird die Race-Bedingung entfernt und 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 'a' erstellen und alle Berechtigungen entfernen, wird ein OSError mit errno.EACCES (Berechtigung verweigert, Fehler 13) errno.EACCES .




Überprüfen Sie os.makedirs : (Es stellt sicher, dass der vollständige Pfad vorhanden ist.)
Fangen Sie OSError ab, um die Tatsache zu behandeln, dass das Verzeichnis möglicherweise vorhanden ist. (Wenn exist_ok False ist (Standardeinstellung), wird ein OSError ausgelöst, wenn das Zielverzeichnis bereits vorhanden ist.)

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass



Ausgehend von Python 3.5 hat pathlib.Path.mkdir ein exist_ok Flag:

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.

(So ​​wie os.makedirs ab python 3.2 ein exists_ok Flag erhalten hat).




Ich habe folgendes niedergelegt. Es ist aber nicht absolut narrensicher.

import os

dirname = 'create/me'

try:
    os.makedirs(dirname)
except OSError:
    if os.path.exists(dirname):
        # We are nearly safe
        pass
    else:
        # There was an error on creation, so make sure we know about it
        raise

Nun, wie ich sage, ist dies nicht wirklich narrensicher, da wir die Möglichkeit haben, das Verzeichnis nicht zu erstellen, und ein anderer Prozess, der es während dieser Zeit erstellt hat.




In Python 3.4 können Sie auch das brandneue pathlib Modul verwenden :

from pathlib import Path
path = Path("/my/directory/filename.txt")
try:
    if not path.parent.exists():
        path.parent.mkdir(parents=True)
except OSError:
    # handle error; you can also catch specific errors like
    # FileExistsError and so on.



Sie können mkpath

# Create a directory and any missing ancestor directories. 
# If the directory already exists, do nothing.

from distutils.dir_util import mkpath
mkpath("test")    

Beachten Sie, dass auch die Vorfahrverzeichnisse erstellt werden.

Es funktioniert für Python 2 und 3.




Für eine IPython.utils.path.ensure_dir_exists() können Sie IPython.utils.path.ensure_dir_exists() :

from IPython.utils.path import ensure_dir_exists
ensure_dir_exists(dir)

Aus der documentation : Stellen Sie sicher, dass ein Verzeichnis vorhanden ist. Wenn es nicht existiert, versuchen Sie, es zu erstellen, und schützen Sie sich vor einer Race-Bedingung, wenn ein anderer Prozess dasselbe tut.




Ich fand dieses Q / A und war anfangs verwirrt von einigen Fehlern und Fehlern, die ich bekam. Ich arbeite in Python 3 (Version 3.5 in einer virtuellen Anaconda-Umgebung auf einem Arch Linux x86_64-System).

Betrachten Sie diese Verzeichnisstruktur:

└── output/         ## dir
   ├── corpus       ## file
   ├── corpus2/     ## dir
   └── subdir/      ## dir

Hier sind meine Experimente / Notizen, die Dinge klären:

# ----------------------------------------------------------------------------
# [1] https://.com/questions/273192/how-can-i-create-a-directory-if-it-does-not-exist

import pathlib

""" Notes:
        1.  Include a trailing slash at the end of the directory path
            ("Method 1," below).
        2.  If a subdirectory in your intended path matches an existing file
            with same name, you will get the following error:
            "NotADirectoryError: [Errno 20] Not a directory:" ...
"""
# Uncomment and try each of these "out_dir" paths, singly:

# ----------------------------------------------------------------------------
# METHOD 1:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but no file created (os.makedirs creates dir, not files!  ;-)
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# [2] https://docs.python.org/3/library/os.html#os.makedirs

# Uncomment these to run "Method 1":

#directory = os.path.dirname(out_dir)
#os.makedirs(directory, mode=0o777, exist_ok=True)

# ----------------------------------------------------------------------------
# METHOD 2:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## works
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## works
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but creates a .../doc.txt./ dir
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# Uncomment these to run "Method 2":

#import os, errno
#try:
#       os.makedirs(out_dir)
#except OSError as e:
#       if e.errno != errno.EEXIST:
#               raise
# ----------------------------------------------------------------------------

Fazit: "Methode 2" ist meiner Meinung nach robuster.

[1] Wie kann ich ein Verzeichnis erstellen, wenn es nicht existiert?

[2] os.makedirs




Sie können os.listdir dafür verwenden:

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')



Wenn Sie folgendes beachten:

os.path.isdir('/tmp/dirname')

bedeutet, dass ein Verzeichnis (Pfad) vorhanden ist UND ein Verzeichnis ist. Also für mich macht dieser Weg das, was ich brauche. So kann ich sicherstellen, dass es Ordner ist (keine Datei) und existiert.




Warum nicht ein Unterprozess-Modul verwenden, wenn es auf einem Computer läuft, der Shell-Sprachen unterstützt? Funktioniert mit Python 2.7 und Python 3.6

from subprocess import call
call(['mkdir', '-p', 'path1/path2/path3'])

Sollte den Trick auf den meisten Systemen tun.




import os
if os.path.isfile(filename):
    print "file exists"
else:
    "Your code here"

Wo sich Ihr Code hier befindet, verwenden Sie den Befehl (Touch)

Dadurch wird geprüft, ob die Datei vorhanden ist. Ist dies nicht der Fall, wird sie erstellt.




Related

python exception path directory operating-system