Więcej
Jak mogę bezpiecznie utworzyć katalog zagnieżdżony?
Jaki jest najbardziej elegancki sposób na sprawdzenie, czy katalog, do którego ma być zapisany plik, istnieje, a jeśli nie, utworzenie katalogu za pomocą Pythona? Oto, co próbowałem:
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)
W jakiś sposób przegapiłem os.path.exists
(dzięki kanja, Blair i Douglas). To jest to, co mam teraz:
def ensure_dir(file_path):
directory = os.path.dirname(file_path)
if not os.path.exists(directory):
os.makedirs(directory)
Czy jest jakaś flaga dla "open", która sprawia, że dzieje się to automatycznie?
3872
3
Widzę dwie odpowiedzi z dobrymi cechami, każda z małą wadą, więc dam moje ujęcie na ten temat:
Spróbuj
os.path.exists
, i rozważos.makedirs
do tworzenia.Jak zauważono w komentarzach i gdzie indziej, istnieje warunek wyścigu – jeśli katalog zostanie utworzony pomiędzy wywołaniami
os.path.exists
ios.makedirs
,os.makedirs
zawiedzie zOSError
. Niestety, wyłapywanieOSError
i kontynuowanie nie jest niezawodne, ponieważ zignoruje niepowodzenie tworzenia katalogu z powodu innych czynników, takich jak niewystarczające uprawnienia, pełny dysk, itp.Jedną z opcji byłoby złapanie
OSError
i zbadanie osadzonego kodu błędu (zobacz Czy istnieje międzyplatformowy sposób na uzyskanie informacji z Python's OSError):Alternatywnie, może być drugi
os.path.exists
, ale załóżmy, że inny utworzył katalog po pierwszym sprawdzeniu, a następnie usunął go przed drugim – nadal możemy zostać oszukani.W zależności od aplikacji, niebezpieczeństwo współbieżnych operacji może być większe lub mniejsze niż niebezpieczeństwo stwarzane przez inne czynniki, takie jak uprawnienia do plików. Programista musiałby wiedzieć więcej o konkretnej tworzonej aplikacji i jej oczekiwanym środowisku przed wyborem implementacji.
Współczesne wersje Pythona dość mocno poprawiają ten kod, zarówno poprzez wyeksponowanie
FileExistsError
(w wersji 3.3+)......i przez umożliwienie argumentu słowa kluczowego do
os.makedirs
o nazwieexist_ok
(w 3.2+).Sprawdź
os.makedirs
: (Upewnia się, że kompletna ścieżka istnieje). Aby obsłużyć fakt, że katalog może istnieć, złapOSError
. (Jeśliexist_ok
jestFalse
(domyślnie), toOSError
jest podnoszony jeśli katalog docelowy już istnieje).Spróbuj funkcji
os.path.exists