Nasıl güvenli bir şekilde iç içe dizin oluşturabilirim?

Bir dosyanın yazılacağı dizinin var olup olmadığını kontrol etmenin ve yoksa Python kullanarak dizini oluşturmanın en şık yolu nedir? İşte denediğim şey:

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)

Her nasılsa os.path.exists dosyasını gözden kaçırmışım (teşekkürler kanja, Blair ve Douglas). Şimdi elimde olan şey bu:

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

Bunun otomatik olarak gerçekleşmesini sağlayan "open" için bir bayrak var mı?

Çözüm

İyi niteliklere sahip iki cevap görüyorum, her birinin küçük bir kusuru var, bu yüzden kendi yorumumu vereceğim:

os.path.exists][1]'i deneyin ve oluşturma için [os.makedirs`]2'yi göz önünde bulundurun.

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

Yorumlarda ve başka yerlerde belirtildiği gibi, bir yarış koşulu vardır – dizin os.path.exists ve os.makedirs çağrıları arasında oluşturulursa, os.makedirs bir OSError ile başarısız olur. Ne yazık ki, OSErrorı genel olarak yakalamak ve devam etmek, yetersiz izinler, dolu disk vb. gibi diğer faktörlerden kaynaklanan dizin oluşturma başarısızlığını göz ardı edeceğinden kusursuz değildir.

Bir seçenek `OSError'ı yakalamak ve gömülü hata kodunu incelemek olabilir (bkz Python'un OSError'ından bilgi almanın platformlar arası bir yolu var mı):

import os, errno

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

Alternatif olarak, ikinci bir os.path.exists olabilir, ancak başka birinin dizini ilk kontrolden sonra oluşturduğunu, ardından ikincisinden önce kaldırdığını varsayalım – yine de kandırılabiliriz.

Uygulamaya bağlı olarak, eşzamanlı işlemlerin tehlikesi, dosya izinleri gibi diğer faktörlerin yarattığı tehlikeden daha fazla veya daha az olabilir. Geliştiricinin bir uygulama seçmeden önce geliştirilmekte olan belirli uygulama ve beklenen ortamı hakkında daha fazla bilgi sahibi olması gerekir.

Python'un modern sürümleri, hem FileExistsError (3.3+'da) ortaya çıkararak bu kodu oldukça geliştirir...

try:
    os.makedirs("path/to/directory")
except FileExistsError:
    # directory already exists
    pass

...ve os.makedirs için exist_ok adında bir anahtar kelime argümanına izin vererek (3.2+'da).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.
Yorumlar (8)

Check os.makedirs: (Yolun tamamının var olduğundan emin olur.) Dizinin var olabileceği gerçeğini ele almak için OSError yakala. (Eğer exist_ok False ise (varsayılan), hedef dizin zaten mevcutsa bir OSError oluşur).

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

os.path.exists`]1 işlevini deneyin

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