Jak bezpiecznie utworzyć katalog zagnieżdżony?

Jaki jest najbardziej elegancki sposób sprawdzenia, czy katalog, do którego ma być zapisany plik, istnieje, a jeśli nie, utwórz go używając 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 Kanji, Blair i Douglasowi). 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 istnieje flaga "open", która powoduje, że dzieje się to automatycznie?

Author: Georgy, 2008-11-07

27 answers

W Pythonie ≥ 3.5, użyj pathlib.Path.mkdir:

from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)
Jeśli chodzi o starsze wersje Pythona, widzę dwie odpowiedzi z dobrymi właściwościami, każda z małą wadą, więc dam swoje zdanie na ten temat:]}

Spróbuj os.path.exists, i rozważ os.makedirs za stworzenie.

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

Jak wspomniano w komentarzach i gdzie indziej, istnieje warunek rasy - jeśli katalog zostanie utworzony między wywołaniami os.path.exists i os.makedirs, os.makedirs zawiedzie się z OSError. Niestety, koc-catching OSError i kontynuowanie nie jest niezawodne, ponieważ zignoruje niepowodzenie utworzenia katalogu z powodu innych czynników, takich jak niewystarczające uprawnienia, pełny dysk itp.

Jedną z opcji byłoby przechwycenie OSError i zbadanie osadzonego kodu błędu (zobacz czy istnieje wieloplatformowy sposób uzyskiwania informacji z OSError Pythona):

import os, errno

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

Alternatywnie, może być drugi os.path.exists, ale załóżmy, że inny utworzył Katalog po pierwszym sprawdzeniu, a następnie go usunął przed drugim-wciąż mogliśmy się nabrać.

W zależności od aplikacji, niebezpieczeństwo jednoczesnych operacji może być większe lub mniejsze niż niebezpieczeństwo stwarzane przez inne czynniki, takie jak uprawnienia plików. Deweloper musiałby wiedzieć więcej o konkretnej aplikacji i jej oczekiwanym środowisku przed wyborem implementacji.

Współczesne wersje Pythona znacznie poprawiają ten kod, zarówno ujawniając FileExistsError (w 3.3+)...

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

...i pozwalając argumentowi słowa kluczowego na os.makedirs o nazwie exist_ok (w 3,2+).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.
 5689
Author: Blair Conrad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-30 09:23:24

Python 3.5+:

import pathlib
pathlib.Path('/my/directory').mkdir(parents=True, exist_ok=True) 

pathlib.Path.mkdir Jak użyto powyżej, rekurencyjnie tworzy katalog i nie wywołuje wyjątku, jeśli katalog już istnieje. Jeśli nie potrzebujesz lub chcesz, aby rodzice zostali stworzeni, pomiń argument parents.

Python 3.2+:

Za pomocą pathlib:

Jeśli możesz, zainstaluj bieżący pathlib backport o nazwie pathlib2. Nie instaluj starszego, niezabezpieczonego backportu o nazwie pathlib. Następnie zapoznaj się z Pythonem 3.5 + sekcja powyżej i używać go tak samo.

Jeśli używasz Pythona 3.4, mimo że jest wyposażony w pathlib, brakuje w nim użytecznej opcji exist_ok. Backport ma oferować nowszą i lepszą implementację mkdir, która zawiera tę brakującą opcję.

Za pomocą os:

import os
os.makedirs(path, exist_ok=True)

os.makedirs Jak użyto powyżej, rekurencyjnie tworzy katalog i nie wywołuje wyjątku, jeśli katalog już istnieje. Ma opcjonalny argument exist_ok tylko wtedy, gdy korzystanie z Pythona 3.2+, z domyślną wartością False. Ten argument nie istnieje w Pythonie 2.x do 2,7. W związku z tym nie ma potrzeby ręcznej obsługi wyjątków, jak w Pythonie 2.7.

Python 2.7+:

Za pomocą pathlib:

Jeśli możesz, zainstaluj bieżący pathlib backport o nazwie pathlib2. Nie instaluj starszego, niezabezpieczonego backportu o nazwie pathlib. Następnie zapoznaj się z powyższą sekcją Pythona 3.5+ i używaj go tak samo.

Za pomocą os:

import os
try: 
    os.makedirs(path)
except OSError:
    if not os.path.isdir(path):
        raise

Podczas gdy naiwny roztwór może najpierw użyć os.path.isdir następnie os.makedirs, powyższe rozwiązanie odwraca kolejność obu operacji. W ten sposób zapobiega powszechnemu warunkowi wyścigu, który ma związek z duplikowaną próbą utworzenia katalogu, a także dezambiguuje pliki z katalogów.

Zauważ, że przechwytywanie wyjątku i używanie errno ma ograniczoną przydatność, ponieważ OSError: [Errno 17] File exists, tj. errno.EEXIST, jest wywoływane zarówno dla plików, jak i katalogi. Bardziej niezawodne jest sprawdzenie, czy katalog istnieje.

Alternatywa:

mkpath tworzy zagnieżdżony katalog i nie robi nic, jeśli katalog już istnieje. Działa to zarówno w Pythonie 2, jak i 3.

import distutils.dir_util
distutils.dir_util.mkpath(path)

Dla Bug 10948 , poważnym ograniczeniem tej alternatywy jest to, że działa ona tylko raz na proces Pythona dla danej ścieżki. Innymi słowy, jeśli użyjesz go do utworzenia katalogu, Usuń katalog z wewnątrz lub poza Pythonem, użyj mkpath ponownie, aby odtworzyć ten sam katalog, {[27] } po prostu po cichu użyje nieprawidłowej buforowanej informacji o wcześniejszym utworzeniu katalogu i nie utworzy ponownie katalogu. W przeciwieństwie do tego, os.makedirs nie opiera się na żadnej takiej pamięci podręcznej. To ograniczenie może być w porządku dla niektórych aplikacji.


W odniesieniu do trybu katalogu , proszę zapoznać się z dokumentacją, jeśli ci na niej zależy.

 1314
Author: Acumenus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 17:16:23

Użycie try except i właściwego kodu błędu z modułu errno pozbawia się warunku wyścigu i jest międzyplatformowe:

import os
import errno

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

Innymi słowy, staramy się tworzyć katalogi, ale jeśli już istnieją, ignorujemy błąd. Z drugiej strony, każdy inny błąd zostanie zgłoszony. Na przykład, jeśli wcześniej utworzysz katalog "a" i usuniesz z niego wszystkie uprawnienia, otrzymasz OSError podniesione z errno.EACCES (Odmowa uprawnień, błąd 13).

 614
Author: Heikki Toivonen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-24 01:55:54

Osobiście polecam użycie os.path.isdir() do testowania zamiast os.path.exists().

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

Jeśli masz:

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

I głupi wkład użytkownika:

:: /tmp/dirname/filename.etc

... Po przejściu tego argumentu do os.makedirs(), jeśli przetestujesz z os.path.exists(), otrzymasz katalog o nazwie filename.etc.

 109
Author: Peter Mortensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-31 14:06:06

Sprawdź os.makedirs: (zapewnia, że pełna ścieżka istnieje.)
Aby poradzić sobie z faktem, że katalog może istnieć, catch OSError. (Jeśli exist_ok jest False (domyślnie), wywołany jest OSError, jeśli katalog docelowy już istnieje.)

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass
 85
Author: Douglas Mayle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-16 12:15:39

Począwszy od Pythona 3.5, pathlib.Path.mkdir posiada flagę exist_ok:

from pathlib import Path
path = Path('/my/directory/filename.txt')
path.parent.mkdir(parents=True, exist_ok=True) 
# path.parent ~ os.path.dirname(path)

To rekurencyjnie tworzy katalog i nie wywołuje wyjątku, jeśli katalog już istnieje.

(tak jak os.makedirs mamy flagę exist_ok zaczynającą się od Pythona 3.2 np os.makedirs(path, exist_ok=True))


Uwaga: kiedy zamieściłem tę odpowiedź, żadna z innych odpowiedzi nie wspomniała exist_ok...

 84
Author: hiro protagonist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-28 06:13:45

Spostrzeżenia na temat specyfiki tej sytuacji

Podajesz konkretny plik na określonej ścieżce i wyciągasz katalog ze ścieżki pliku. Następnie po upewnieniu się, że masz katalog, próbujesz otworzyć plik do odczytu. Aby skomentować ten kod:

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

Chcemy uniknąć nadpisywania wbudowanej funkcji, dir. Poza tym filepath a Może fullfilepath jest chyba lepszą nazwą semantyczną niż filename więc lepiej by było napisać:

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

Twój koniec celem jest otwarcie tego pliku, który początkowo określasz, do napisania, ale zasadniczo zbliżasz się do tego celu (na podstawie kodu) w taki sposób, który otwiera plik dla czytania:

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

Zakładając otwarcie do czytania

Dlaczego tworzysz katalog dla pliku, który spodziewasz się, że tam będzie i będzie w stanie odczytać?

Po prostu spróbuj otworzyć plik.
with open(filepath) as my_file:
    do_stuff(my_file)

Jeśli katalogu lub pliku nie ma, otrzymasz {[11] } z powiązanym numer błędu: errno.ENOENT wskaże poprawny numer błędu niezależnie od platformy. Możesz go złapać, jeśli chcesz, na przykład:

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

Zakładając, że otwieramy się do pisania

To jest prawdopodobnie to czego pragniesz.

W tym przypadku, prawdopodobnie nie mamy do czynienia z żadnymi warunkami wyścigowymi. Po prostu rób to, co było, ale pamiętaj, że do pisania musisz otworzyć tryb w (lub a, aby dołączyć). Jest to również najlepsza praktyka Pythona, aby korzystać z menedżera kontekstu do otwierania plików.

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

Powiedzmy jednak, że mamy kilka procesów Pythona, które próbują umieścić wszystkie swoje dane w tym samym katalogu. Wtedy możemy mieć spór o utworzenie katalogu. W takim przypadku najlepiej zawinąć wywołanie makedirs W blok try-except.

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)
 48
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-01 21:54:27

Spróbuj os.path.exists function

if not os.path.exists(dir):
    os.mkdir(dir)
 37
Author: gone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-15 16:05:12

Odłożyłem następujące rzeczy. Nie jest jednak całkowicie niezawodny.

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

Teraz, jak mówię, nie jest to tak naprawdę niezawodne, ponieważ mamy możliwość nie utworzenia katalogu i innego procesu tworzącego go w tym okresie.

 33
Author: Ali Afshar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-31 14:05:11

Sprawdzić, czy katalog istnieje i utworzyć go w razie potrzeby?

Bezpośrednią odpowiedzią na to jest, zakładając prostą sytuację, w której nie spodziewasz się, że inni użytkownicy lub procesy będą mieszać z Twoim katalogiem:

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

Lub jeśli tworzenie katalogu podlega Warunkom wyścigu (tzn. jeśli po sprawdzeniu ścieżki istnieje, coś innego mogło już to zrobić) zrób to:

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

Ale być może jeszcze lepszym podejściem jest omijanie problem contention zasobów, używając katalogów tymczasowych poprzez tempfile:

import tempfile

d = tempfile.mkdtemp()

Oto podstawowe informacje z internetowego dokumentu:

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.

Nowy w Pythonie 3.5: pathlib.Path z exist_ok

Pojawił się nowy obiekt Path (od wersji 3.4) z wieloma metodami, których można by użyć ze ścieżkami - jedną z nich jest mkdir.

(dla kontekstu śledzę mojego cotygodniowego przedstawiciela za pomocą skryptu. Oto odpowiednie fragmenty kodu ze skryptu, które pozwalają mi uniknąć trafienie przepełnienia stosu więcej niż raz dziennie dla tych samych danych.)

Najpierw właściwy przywóz:

from pathlib import Path
import tempfile

Nie musimy teraz zajmować się os.path.join - wystarczy połączyć części ścieżki z /:

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

Następnie idempotentnie upewniam się, że katalog istnieje - argument exist_ok pojawia się w Pythonie 3.5:

directory.mkdir(exist_ok=True)

Oto odpowiednia część dokumentacji :

Jeśli exist_ok jest prawdą, FileExistsError wyjątki będą ignorowane (takie samo zachowanie jak POSIX mkdir -p polecenie), ale tylko wtedy, gdy ostatni komponent path nie jest istniejącym plikiem niebędącym katalogiem.

Tutaj jest trochę więcej skryptu - w moim przypadku, nie podlegam warunkowi rasy, mam tylko jeden proces, który oczekuje, że katalog (lub zawarte pliki) tam będzie, i nie mam nic próbuje usunąć katalog.

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

Path obiekty muszą być wymuszone na str, zanim Inne API oczekujące ścieżek str będą mogły z nich korzystać.

Być może Pandy powinny być zaktualizowano, aby zaakceptować instancje abstrakcyjnej klasy bazowej, os.PathLike.

 25
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-07 03:19:31

W Pythonie 3.4 możesz również użyć modułu brand new pathlib :

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.
 20
Author: Antti Haapala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-11 20:50:01

In Python3, os.makedirs obsługuje ustawienie exist_ok. Domyślnym ustawieniem jest False, co oznacza, że OSError zostanie podniesiony, jeśli katalog docelowy już istnieje. Poprzez ustawienie exist_ok na True, OSError (katalog istnieje) zostanie zignorowany i katalog nie zostanie utworzony.

os.makedirs(path,exist_ok=True)

In Python2, os.makedirs nie obsługuje ustawienia exist_ok. Możesz użyć podejścia w Heikki-Toivonen ' s answer :

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise
 15
Author: euccas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:31

Odpowiednia dokumentacja Pythona sugeruje użycie stylu kodowania EAFP (łatwiej prosić o przebaczenie niż pozwolenie) . Oznacza to, że kod

try:
    os.makedirs(path)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise
    else:
        print "\nBE CAREFUL! Directory %s already exists." % path

Jest lepszy niż alternatywa

if not os.path.exists(path):
    os.makedirs(path)
else:
    print "\nBE CAREFUL! Directory %s already exists." % path

Dokumentacja sugeruje to dokładnie ze względu na stan rasy omówiony w tym pytaniu. Ponadto, jak wspominają tutaj inni, istnieje przewaga wydajności w zapytaniu raz zamiast dwa razy systemu operacyjnego. Wreszcie argument wysunięty do przodu, potencjalnie, za drugim kodem w niektórych przypadkach-gdy programista zna środowisko uruchomionej aplikacji - może być zalecany tylko w szczególnym przypadku, gdy program skonfigurował prywatne środowisko dla siebie (i innych instancji tego samego programu).

Nawet w takim przypadku jest to zła praktyka i może prowadzić do długiego bezużytecznego debugowania. Na przykład, fakt, że ustawiliśmy uprawnienia dla katalogu nie powinien pozostawić nam uprawnienia wrażenie są ustawione odpowiednio do naszych celów. Katalog nadrzędny może być montowany z innymi uprawnieniami. Ogólnie rzecz biorąc, program powinien zawsze działać poprawnie i programista nie powinien oczekiwać jednego konkretnego środowiska.

 13
Author: kavadias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 03:12:48

W przypadku rozwiązania jednowarstwowego można użyć IPython.utils.path.ensure_dir_exists():

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

Z dokumentacji: upewnij się, że katalog istnieje. Jeśli nie istnieje, spróbuj go utworzyć i chronić przed stanem rasy, jeśli inny proces robi to samo.

 13
Author: tashuhka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-16 12:25:51

Możesz użyć mkpath

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

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

Zauważ, że utworzy również katalogi nadrzędne.

Działa dla Pythona 2 i 3.

 9
Author: Dennis Golomazov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-13 21:44:56

Używam os.path.exists(), Tutaj jest skryptem Pythona 3, który może być użyty do sprawdzenia, czy katalog istnieje, utworzenia go, jeśli nie istnieje, i usunięcia go, jeśli istnieje (w razie potrzeby).

Monituje użytkowników o wprowadzenie katalogu i może być łatwo modyfikowany.

 8
Author: Michael Strobel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 03:16:11

Znalazłem ten Q / A i początkowo byłem zaskoczony niektórymi niepowodzeniami i błędami, które otrzymywałem. Pracuję w Pythonie 3 (V. 3. 5 w środowisku wirtualnym Anaconda na systemie Arch Linux x86_64).

Rozważmy tę strukturę katalogów:

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

Oto moje eksperymenty / notatki, które wyjaśniają rzeczy:

# ----------------------------------------------------------------------------
# [1] https://stackoverflow.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
# ----------------------------------------------------------------------------

Wniosek: moim zdaniem" metoda 2 " jest bardziej solidna.

[1] Jak mogę utworzyć katalog, jeśli nie istnieje?

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

 7
Author: Victoria Stuart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-16 19:26:08

Użyj tego polecenia sprawdź i utwórz katalog

 if not os.path.isdir(test_img_dir):
     os.mkdir(test_img_dir)
 7
Author: Manivannan Murugavel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-16 19:07:54

Dlaczego nie użyć modułu podprocesowego, jeśli działa na maszynie obsługującej polecenia mkdir z opcją -p? Działa na Pythonie 2.7 i Pythonie 3.6

from subprocess import call
call(['mkdir', '-p', 'path1/path2/path3'])
Powinno zadziałać na większości systemów.

W sytuacjach, w których przenośność nie ma znaczenia (np. przy użyciu Dockera) rozwiązaniem są czyste 2 linie. Nie musisz też dodawać logiki, aby sprawdzić, czy katalogi istnieją, czy nie. Wreszcie, bezpiecznie jest ponownie uruchomić bez żadnych skutków ubocznych

Jeśli potrzebujesz obsługi błędów:

from subprocess import check_call
try:
    check_call(['mkdir', '-p', 'path1/path2/path3'])
except:
    handle...
 7
Author: Geoff Paul Bremner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-16 19:37:30

Zobaczyłem Heikki Toivonen i A-B-B 'S odpowiedzi i pomyślałem o tej odmianie.

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
 6
Author: alissonmuller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 03:14:29

Możesz użyć os.listdir do tego:

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')
 5
Author: iPhynx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-30 12:31:13

Wywołanie funkcji create_dir() w punkcie wejścia programu / projektu.

import os

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

create_dir('Project directory')
 5
Author: Steffi Keran Rani J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-28 16:00:40

Musisz ustawić pełną ścieżkę przed utworzeniem katalogu:

import os,sys,inspect
import pathlib

currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
your_folder = currentdir + "/" + "your_folder"

if not os.path.exists(your_folder):
   pathlib.Path(your_folder).mkdir(parents=True, exist_ok=True)

To działa dla mnie i mam nadzieję, że będzie działać również dla ciebie

 4
Author: Hussam Kurd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-19 00:40:45

Jeśli wziąć pod uwagę:

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

Oznacza, że katalog (ścieżka) istnieje i jest katalogiem. Więc dla mnie ten sposób robi to, czego potrzebuję. Więc mogę się upewnić, że jest to folder (Nie plik) i istnieje.

 3
Author: Ralph Schwerdt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-03 16:35:48
import os
if os.path.isfile(filename):
    print "file exists"
else:
    "Your code here"

Gdzie twój kod tutaj jest użyj polecenia (dotknij)

To sprawdzi, czy plik tam jest, jeśli go nie ma, to go utworzy.

 0
Author: Evil Exists,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-05 23:15:27

Pod Linuksem można utworzyć katalog w jednej linii:

import os
os.system("mkdir -p {0}".format('mydir'))
 0
Author: Sergiy Maksymenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-10 03:39:26

Możesz utworzyć zarówno Plik, jak i wszystkie jego katalogi nadrzędne w jednym poleceniu z rozszerzeniem fastcore do pathlib: path.mk_write(data)

from fastcore.utils import Path
Path('/dir/to/file.txt').mk_write('Hello World')
 0
Author: korakot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-22 03:32:43