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




python windows ordner erstellen (17)

Prüfen Sie, ob ein Verzeichnis existiert und erstellen Sie es ggf.?

Die direkte Antwort auf diese Frage lautet, eine einfache Situation vorauszusetzen, in der Sie nicht erwarten, dass andere Benutzer oder Prozesse Ihr Verzeichnis durcheinander bringen:

if not os.path.exists(d):
    os.makedirs(d)

oder wenn das Erstellen des Verzeichnisses Race-Bedingungen unterliegt (dh wenn nach der Überprüfung des Pfads ein anderer Pfad bereits erstellt wurde), machen Sie Folgendes:

import errno
try:
    os.makedirs(d)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise

Ein noch besserer Ansatz ist es jedoch, das Problem mit Ressourcenkonflikten zu umgehen, indem temporäre Verzeichnisse über tempfile :

import tempfile

d = tempfile.mkdtemp()

Hier ist das Wesentliche aus dem Online-Dokument:

mkdtemp(suffix='', prefix='tmp', dir=None)
    User-callable function to create and return a unique temporary
    directory.  The return value is the pathname of the directory.

    The directory is readable, writable, and searchable only by the
    creating user.

    Caller is responsible for deleting the directory when done with it.

Neu in Python 3.5: pathlib.Path mit exist_ok

Es gibt ein neues Path Objekt (ab 3.4) mit vielen Methoden, die man mit Pfaden verwenden möchte - eine davon ist mkdir .

(Im Kontext verfolge ich meine wöchentliche Wiederholung mit einem Skript. Hier sind die relevanten Teile des Codes aus dem Skript, die es mir ermöglichen, zu vermeiden, dass Stack Overflow für dieselben Daten mehr als einmal am Tag getroffen wird.)

Zuerst die relevanten Importe:

from pathlib import Path
import tempfile

Wir müssen uns jetzt nicht mit os.path.join befassen - verbinden Sie einfach os.path.join mit einem / :

directory = Path(tempfile.gettempdir()) / 'sodata'

Dann vergewissere ich mich idempotently, dass das Verzeichnis existiert - das Argument exist_ok in Python 3.5:

directory.mkdir(exist_ok=True)

Hier ist der relevante Teil der pathlib.Path.mkdir :

Wenn exist_ok true exist_ok ist, werden FileExistsError Ausnahmen ignoriert (dasselbe Verhalten wie der POSIX mkdir -p Befehl POSIX mkdir -p ), jedoch nur, wenn die letzte Pfadkomponente keine vorhandene Nichtverzeichnisdatei ist.

Hier ist ein bisschen mehr vom Skript - in meinem Fall bin ich nicht an eine Race-Bedingung gebunden. Ich habe nur einen Prozess, der erwartet, dass das Verzeichnis (oder die enthaltenen Dateien) vorhanden sind, und ich habe nichts zu entfernen versucht das Verzeichnis.

todays_file = directory / str(datetime.datetime.utcnow().date())
if todays_file.exists():
    logger.info("todays_file exists: " + str(todays_file))
    df = pd.read_json(str(todays_file))

Pfadobjekte müssen in str erzwungen werden, bevor andere APIs, die str Pfade erwarten, sie verwenden können.

Möglicherweise sollten Pandas aktualisiert werden, um Instanzen der abstrakten Basisklasse os.PathLike zu akzeptieren.

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?


Einblicke in die Besonderheiten dieser Situation

Sie geben eine bestimmte Datei an einem bestimmten Pfad an und ziehen das Verzeichnis aus dem Dateipfad. Nachdem Sie sichergestellt haben, dass Sie über das Verzeichnis verfügen, versuchen Sie, eine Datei zum Lesen zu öffnen. Um diesen Code zu kommentieren:

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

Wir möchten vermeiden, dass die eingebaute Funktion, dh, überschrieben wird. filepath oder fullfilepath ist wahrscheinlich ein besserer semantischer Name als filename daher wäre dies besser geschrieben:

import os
filepath = '/my/directory/filename.txt'
directory = os.path.dirname(filepath)

Ihr Endziel ist es, diese Datei, wie Sie anfangs angeben, zum Schreiben zu öffnen, aber Sie nähern sich diesem Ziel (basierend auf Ihrem Code) wie folgt, wodurch die Datei zum Lesen geöffnet wird:

if not os.path.exists(directory):
    os.makedirs(directory)
f = file(filename)

Vorausgesetzt Öffnung zum Lesen

Warum sollten Sie ein Verzeichnis für eine Datei erstellen, von der Sie erwarten, dass sie dort ist und lesen kann?

Versuchen Sie einfach, die Datei zu öffnen.

with open(filepath) as my_file:
    do_stuff(my_file)

Wenn das Verzeichnis oder die Datei nicht vorhanden ist, erhalten Sie einen IOError mit einer zugehörigen Fehlernummer: errno.ENOENT zeigt unabhängig von Ihrer Plattform auf die richtige Fehlernummer. Sie können es fangen, wenn Sie möchten, zum Beispiel:

import errno
try:
    with open(filepath) as my_file:
        do_stuff(my_file)
except IOError as error:
    if error.errno == errno.ENOENT:
        print 'ignoring error because directory or file is not there'
    else:
        raise

Angenommen, wir öffnen uns zum Schreiben

Das ist wahrscheinlich was Sie wollen.

In diesem Fall haben wir wahrscheinlich keine Rennbedingungen. Also machen Sie einfach so, wie Sie waren, aber beachten Sie, dass Sie zum Schreiben mit dem Modus w (oder a anhängenden) öffnen müssen. Es ist auch eine bewährte Methode in Python, den Kontext-Manager zum Öffnen von Dateien zu verwenden.

import os
if not os.path.exists(directory):
    os.makedirs(directory)
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

Angenommen, wir haben mehrere Python-Prozesse, die versuchen, alle ihre Daten in dasselbe Verzeichnis zu legen. Dann kann es zu Konflikten bei der Erstellung des Verzeichnisses kommen. In diesem Fall makedirs den makedirs Aufruf am besten in einen Try- makedirs -Block.

import os
import errno
if not os.path.exists(directory):
    try:
        os.makedirs(directory)
    except OSError as error:
        if error.errno != errno.EEXIST:
            raise
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

Ü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).


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


Ich sah Heikki Toivonen und share Antworten und dachte an diese Variation.

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST or not os.path.isdir(path):
            raise

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.


Ich würde persönlich empfehlen, dass Sie os.path.isdir() anstelle von os.path.exists() zum Testen verwenden.

>>> os.path.exists('/tmp/dirname')
True
>>> os.path.exists('/tmp/dirname/filename.etc')
True
>>> os.path.isdir('/tmp/dirname/filename.etc')
False
>>> os.path.isdir('/tmp/fakedirname')
False

Wenn Sie haben:

>>> dir = raw_input(":: ")

Und eine dumme Benutzereingabe:

:: /tmp/dirname/filename.etc

... Sie erhalten am Ende ein Verzeichnis namens filename.etc wenn Sie dieses Argument an os.makedirs() wenn Sie mit os.path.exists() testen.


In Python3 unterstützt os.makedirs die Einstellung exist_ok . Die Standardeinstellung ist False . OSError bedeutet, dass ein OSError wird, wenn das Zielverzeichnis bereits vorhanden ist. Wenn Sie exist_ok auf True , wird OSError (Verzeichnis existiert) ignoriert und das Verzeichnis wird nicht erstellt.

os.makedirs(path,exist_ok=True)

In Python2 unterstützt os.makedirs die Einstellung exist_ok . Sie können den Ansatz in der Antwort von heikki-toivonen verwenden :

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 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 .


Probieren Sie die Funktion os.path.exists aus

if not os.path.exists(dir):
    os.mkdir(dir)

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

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

Bei der Arbeit mit Datei-E / A ist Folgendes zu beachten

TOCTTOU (Zeitpunkt der Überprüfung bis zum Zeitpunkt der Verwendung)

ifWenn Sie also eine Prüfung durchführen und später lesen oder schreiben, kann dies zu einer nicht behandelten E / A-Ausnahme führen. Am besten geht es:

try:
    os.makedirs(dir_path)
except OSError as e:
    if e.errno != errno.EEXIS:
        raise

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.


Rufen Sie die Funktion create_dir()am Einstiegspunkt Ihres Programms / Projekts auf.

import os

def create_dir(directory):
    if not os.path.exists(directory):
        print('Creating Directory '+directory)
        os.makedirs(directory)

create_dir('Project directory')

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.







operating-system