Bagaimana saya bisa dengan aman membuat direktori bersarang?

4249

Apa cara paling elegan untuk memeriksa apakah direktori file akan ditulis ada, dan jika tidak, buat direktori menggunakan Python? Inilah yang saya coba:

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)

Entah bagaimana, saya merindukan os.path.exists(terima kasih kanja, Blair, dan Douglas). Inilah yang saya miliki sekarang:

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

Apakah ada bendera untuk "terbuka", yang membuat ini terjadi secara otomatis?

Parand
sumber
27
Secara umum Anda mungkin perlu menjelaskan kasus di mana tidak ada direktori dalam nama file. Pada dirname komputer saya ('foo.txt') memberikan '', yang tidak ada dan menyebabkan makedirs () gagal.
Brian Hawkins
11
Dalam python 2.7 os.path.mkdirtidak ada. Ini os.mkdir.
drevicko
6
jika path ada, seseorang tidak hanya harus memeriksa apakah itu direktori dan bukan file biasa atau objek lain (banyak jawaban memeriksa ini), juga perlu memeriksa apakah itu dapat ditulis (saya tidak menemukan jawaban yang memeriksa ini)
miracle173
9
Jika Anda datang ke sini untuk membuat direktori induk dari string jalur file p, berikut ini adalah cuplikan kode saya:os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
Thamme Gowda

Jawaban:

5193

Pada Python ≥ 3.5, gunakan pathlib.Path.mkdir:

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

Untuk versi Python yang lebih lama, saya melihat dua jawaban dengan kualitas yang bagus, masing-masing dengan cacat kecil, jadi saya akan berikan pendapat saya:

Coba os.path.exists, dan pertimbangkan os.makedirsuntuk penciptaan.

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

Seperti disebutkan dalam komentar dan di tempat lain, ada kondisi balapan - jika direktori dibuat antara os.path.existsdan os.makedirspanggilan, os.makedirsakan gagal dengan OSError. Sayangnya, blanket-catching OSErrordan continue tidak mudah, karena akan mengabaikan kegagalan untuk membuat direktori karena faktor lain, seperti izin yang tidak mencukupi, disk penuh, dll.

Salah satu opsi adalah untuk menjebak OSErrordan memeriksa kode kesalahan tertanam (lihat Apakah ada cara lintas platform untuk mendapatkan informasi dari OSError Python ):

import os, errno

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

Atau, mungkin ada yang kedua os.path.exists, tapi anggap yang lain membuat direktori setelah cek pertama, lalu menghapusnya sebelum yang kedua - kita masih bisa tertipu.

Tergantung pada aplikasinya, bahaya operasi bersamaan mungkin lebih atau kurang dari bahaya yang ditimbulkan oleh faktor-faktor lain seperti izin file. Pengembang harus mengetahui lebih banyak tentang aplikasi tertentu yang sedang dikembangkan dan lingkungan yang diharapkan sebelum memilih suatu implementasi.

Versi modern Python meningkatkan sedikit kode ini, baik dengan mengekspos FileExistsError(dalam 3.3 +) ...

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

... dan dengan mengizinkan argumen kata kunci os.makedirsdipanggilexist_ok (dalam 3.2+).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.
Blair Conrad
sumber
5
Kondisi balapan adalah poin yang baik, tetapi pendekatan di stackoverflow.com/questions/273192/#273208 , akan menutupi kegagalan untuk membuat direktori. Jangan merasa buruk karena memilih turun - Anda tidak suka jawabannya. Untuk apa suara itu?
Blair Conrad
27
Ingat bahwa os.path.exists () tidak gratis. Jika kasus normal adalah bahwa direktori akan ada di sana, maka kasus di mana itu tidak seharusnya ditangani sebagai pengecualian. Dengan kata lain, cobalah untuk membuka dan menulis ke file Anda, menangkap pengecualian OSError dan, berdasarkan errno, lakukan makedir Anda () dan coba kembali atau angkat kembali. Ini menciptakan duplikasi kode kecuali Anda membungkus tulisan dalam metode lokal.
Andrew
22
os.path.existsjuga mengembalikan Truefile. Saya telah mengirim jawaban untuk mengatasi ini.
Acumenus
13
Sebagai komentator untuk jawaban lain di sini telah mencatat, exists_okparameter untuk os.makedirs()dapat digunakan untuk mencakup bagaimana keberadaan sebelumnya dari jalur ditangani, karena Python 3.2.
Bobble
6
os.mkdirs()dapat membuat folder yang tidak diinginkan jika pemisah jalur tidak sengaja ditinggalkan, folder saat ini tidak seperti yang diharapkan, elemen jalur berisi pemisah jalur. Jika Anda menggunakan os.mkdir()bug ini akan menimbulkan pengecualian, mengingatkan Anda akan keberadaannya.
drevicko
1242

Python 3.5+:

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

pathlib.Path.mkdirseperti yang digunakan di atas secara rekursif membuat direktori dan tidak menimbulkan pengecualian jika direktori tersebut sudah ada. Jika Anda tidak perlu atau ingin orang tua dibuat, lewati parentsargumen.

Python 3.2+:

Menggunakan pathlib:

Jika Anda bisa, instal pathlibbackport saat ini bernama pathlib2. Jangan pasang backport yang tidak terawat dengan nama pathlib. Selanjutnya, lihat bagian Python 3.5+ di atas dan gunakan yang sama.

Jika menggunakan Python 3.4, meskipun sudah ada pathlib, ia tidak memiliki exist_okopsi yang berguna . Backport dimaksudkan untuk menawarkan implementasi yang lebih baru dan lebih unggul mkdiryang mencakup opsi yang hilang ini.

Menggunakan os:

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

os.makedirsseperti yang digunakan di atas secara rekursif membuat direktori dan tidak menimbulkan pengecualian jika direktori tersebut sudah ada. Ini memiliki exist_okargumen opsional hanya jika menggunakan Python 3.2+, dengan nilai default False. Argumen ini tidak ada dalam Python 2.x hingga 2.7. Dengan demikian, tidak perlu penanganan pengecualian manual seperti dengan Python 2.7.

Python 2.7+:

Menggunakan pathlib:

Jika Anda bisa, instal pathlibbackport saat ini bernama pathlib2. Jangan pasang backport yang tidak terawat dengan nama pathlib. Selanjutnya, lihat bagian Python 3.5+ di atas dan gunakan yang sama.

Menggunakan os:

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

Sementara solusi naif dapat digunakan pertama kali os.path.isdirdiikuti oleh os.makedirs, solusi di atas membalikkan urutan kedua operasi. Dengan demikian, ini mencegah kondisi ras umum yang berkaitan dengan upaya duplikasi dalam membuat direktori, dan juga memisahkan file dari direktori.

Perhatikan bahwa menangkap pengecualian dan menggunakan errnoadalah kegunaan terbatas karena OSError: [Errno 17] File exists, yaitu errno.EEXISTdinaikkan untuk file dan direktori. Lebih dapat diandalkan hanya untuk memeriksa apakah direktori tersebut ada.

Alternatif:

mkpathmembuat direktori bersarang, dan tidak melakukan apa pun jika direktori sudah ada. Ini berfungsi di kedua Python 2 dan 3.

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

Per Bug 10948 , batasan parah dari alternatif ini adalah bahwa ia hanya bekerja sekali per proses python untuk jalur yang diberikan. Dengan kata lain, jika Anda menggunakannya untuk membuat direktori, lalu hapus direktori dari dalam atau di luar Python, kemudian gunakan mkpathlagi untuk membuat ulang direktori yang sama, mkpathcukup diam-diam akan menggunakan informasi cache yang tidak valid karena sebelumnya telah membuat direktori, dan tidak akan sebenarnya buat direktori lagi. Sebaliknya, os.makedirstidak bergantung pada cache semacam itu. Batasan ini mungkin oke untuk beberapa aplikasi.


Berkenaan dengan mode direktori , silakan merujuk ke dokumentasi jika Anda peduli.

Acumenus
sumber
13
Jawaban ini mencakup hampir setiap kasus khusus sejauh yang saya tahu. Saya berencana untuk membungkus ini dalam "jika tidak os.path.isdir ()" meskipun karena saya berharap direktori ada hampir setiap waktu dan saya dapat menghindari pengecualian seperti itu.
Charles L.
5
@CharlesL. Pengecualian mungkin lebih murah daripada disk IO cek, jika alasan Anda adalah kinerja.
jpmc26
1
@ jpmc26 tetapi makedir melakukan stat tambahan, umask, lstat ketika hanya memeriksa untuk melempar OSError.
kwarunek
4
Ini adalah jawaban yang salah, karena memperkenalkan kondisi lomba FS yang potensial. Lihat jawaban dari Aaron Hall.
sleepycal
4
seperti yang dikatakan @sleepycal, ini menderita kondisi ras yang sama dengan jawaban yang diterima. Jika antara menaikkan kesalahan dan memeriksa os.path.isdirorang lain menghapus folder, Anda akan menaikkan kesalahan, usang, dan membingungkan bahwa folder itu ada.
farmir
604

Menggunakan try kecuali dan kode kesalahan yang tepat dari modul errno menghilangkan kondisi balapan dan bersifat cross-platform:

import os
import errno

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

Dengan kata lain, kami mencoba membuat direktori, tetapi jika sudah ada kami mengabaikan kesalahan. Di sisi lain, setiap kesalahan lain akan dilaporkan. Misalnya, jika Anda membuat dir 'a' sebelumnya dan menghapus semua izin darinya, Anda akan mendapatkan OSErrorkenaikan errno.EACCESgaji (Izin ditolak, kesalahan 13).

Heikki Toivonen
sumber
24
Jawaban yang diterima sebenarnya berbahaya karena memiliki kondisi ras. Itu lebih sederhana, jadi, jika Anda tidak mengetahui kondisi ras, atau berpikir itu tidak berlaku untuk Anda, itu akan menjadi pilihan pertama Anda.
Heikki Toivonen
15
Menaikkan pengecualian hanya ketika exception.errno != errno.EEXISTtidak sengaja akan mengabaikan kasus ketika path ada tetapi merupakan objek non-direktori seperti file. Pengecualian idealnya dinaikkan jika path adalah objek non-direktori.
Acumenus
178
Perhatikan bahwa kode di atas setara denganos.makedirs(path,exist_ok=True)
Navin
58
@Navin exist_okParameter diperkenalkan dalam Python 3.2. Itu tidak ada dalam Python 2.x. Saya akan memasukkannya ke dalam jawaban saya.
Acumenus
26
@HeikkiToivonen Secara teknis, jika program lain memodifikasi direktori dan file pada waktu yang bersamaan dengan program Anda, seluruh program Anda adalah satu kondisi balap raksasa. Apa yang harus menghentikan program lain dari hanya menghapus direktori ini setelah kode membuatnya dan sebelum Anda benar-benar memasukkan file ke dalamnya?
jpmc26
102

Saya pribadi merekomendasikan agar Anda menggunakan os.path.isdir()untuk menguji daripada 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

Jika Anda memiliki:

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

Dan input pengguna bodoh:

:: /tmp/dirname/filename.etc

... Anda akan berakhir dengan direktori bernama filename.etcketika Anda meneruskan argumen itu os.makedirs()jika Anda mengujinya os.path.exists().

Peter Mortensen
sumber
8
Jika Anda hanya menggunakan 'isdir', tidakkah Anda masih memiliki masalah ketika Anda mencoba membuat direktori dan file dengan nama yang sama sudah ada?
MrWificent
3
@ MrWireless Pengecualian yang dihasilkan saat membuat direktori di atas file yang ada akan dengan benar mencerminkan masalah kembali ke pemanggil.
Damian Yerrick
79

Periksa os.makedirs: (Memastikan path lengkap ada.)
Untuk menangani fakta direktori mungkin ada, tangkap OSError. (Jika exist_okadalah False(default), sebuah OSErrordinaikkan jika direktori target sudah ada.)

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass
Douglas Mayle
sumber
19
dengan try / kecuali, Anda akan menutupi kesalahan dalam pembuatan direktori, dalam kasus ketika direktori tidak ada tetapi untuk beberapa alasan Anda tidak dapat membuatnya
Blair Conrad
3
OSErrorakan dimunculkan di sini jika path adalah file atau direktori yang ada. Saya telah mengirim jawaban untuk mengatasi ini.
Acumenus
4
Ini setengah jalan di sana. Anda perlu memeriksa kondisi sub-kesalahan OSErrorsebelum memutuskan untuk mengabaikannya. Lihat stackoverflow.com/a/5032238/763269 .
Chris Johnson
71

Mulai dari Python 3.5, pathlib.Path.mkdirmemiliki exist_okbendera:

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

Ini secara rekursif membuat direktori dan tidak memunculkan pengecualian jika direktori tersebut sudah ada.

(Sama seperti os.makedirsmendapat exist_okbendera mulai dari python 3.2 misalnya os.makedirs(path, exist_ok=True))

hiro protagonis
sumber
46

Wawasan spesifik situasi ini

Anda memberikan file tertentu di jalur tertentu dan Anda menarik direktori dari jalur file. Kemudian setelah memastikan Anda memiliki direktori, Anda mencoba membuka file untuk dibaca. Untuk mengomentari kode ini:

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

Kami ingin menghindari menimpa fungsi builtin dir,. Juga, filepathatau mungkin fullfilepathmungkin nama semantik yang lebih baik daripada filenameini akan lebih baik ditulis:

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

Tujuan akhir Anda adalah untuk membuka file ini, pada awalnya Anda menyatakan, untuk menulis, tetapi Anda pada dasarnya mendekati tujuan ini (berdasarkan kode Anda) seperti ini, yang membuka file untuk membaca :

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

Dengan asumsi pembukaan untuk membaca

Mengapa Anda membuat direktori untuk file yang Anda harapkan ada di sana dan dapat membaca?

Coba saja buka file.

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

Jika direktori atau file tidak ada, Anda akan mendapatkan IOErrordengan nomor kesalahan terkait: errno.ENOENTakan menunjuk ke nomor kesalahan yang benar terlepas dari platform Anda. Anda dapat menangkapnya jika mau, misalnya:

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

Dengan asumsi kita membuka diri untuk menulis

Ini mungkin yang Anda inginkan.

Dalam hal ini, kami mungkin tidak menghadapi kondisi balapan apa pun. Jadi lakukan saja apa adanya, tetapi perhatikan bahwa untuk menulis, Anda harus membuka dengan wmode (atau amenambahkan). Ini juga merupakan praktik terbaik Python untuk menggunakan manajer konteks untuk membuka file.

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

Namun, katakanlah kami memiliki beberapa proses Python yang mencoba untuk menempatkan semua data mereka ke direktori yang sama. Maka kita mungkin memiliki pendapat tentang pembuatan direktori. Dalam hal ini yang terbaik adalah membungkus makedirspanggilan dalam blok coba-kecuali.

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)
Aaron Hall
sumber
34

Coba os.path.existsfungsinya

if not os.path.exists(dir):
    os.mkdir(dir)
pergi
sumber
3
Saya akan mengomentari pertanyaan itu, tetapi apakah maksud kami os.mkdir? Python saya (2.5.2) tidak memiliki os.path.mkdir ....
Blair Conrad
1
Tidak ada os.path.mkdir()metode. Modul os.path mengimplementasikan beberapa fungsi yang berguna pada nama path .
Serge S.
31

Saya telah meletakkan berikut ini. Ini tidak sepenuhnya sangat mudah sekalipun.

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

Sekarang seperti yang saya katakan, ini bukan benar-benar sangat mudah, karena kami memiliki kemungkinan gagal membuat direktori, dan proses lain membuatnya selama periode itu.

Ali Afshar
sumber
Dua masalah: (1) Anda perlu memeriksa kondisi sub-kesalahan OSError sebelum memutuskan untuk memeriksa os.path.exists- lihat stackoverflow.com/a/5032238/763269, dan (2) keberhasilan os.path.existstidak berarti direktori itu ada, hanya jalurnya saja ada - bisa berupa file, atau symlink, atau objek sistem file lainnya.
Chris Johnson
24

Periksa apakah ada direktori dan buat jika perlu?

Jawaban langsung untuk ini adalah, dengan asumsi situasi sederhana di mana Anda tidak mengharapkan pengguna lain atau proses untuk mengacaukan direktori Anda:

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

atau jika membuat direktori tunduk pada kondisi balapan (yaitu jika setelah memeriksa jalur ada, sesuatu yang lain mungkin telah membuatnya) lakukan ini:

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

Tapi mungkin pendekatan yang lebih baik adalah menghindari masalah pertentangan sumber daya, dengan menggunakan direktori sementara melalui tempfile:

import tempfile

d = tempfile.mkdtemp()

Inilah hal-hal penting dari dokumen online:

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.

Baru dalam Python 3.5: pathlib.Pathdenganexist_ok

Ada Pathobjek baru (pada 3.4) dengan banyak metode yang ingin digunakan dengan path - salah satunya mkdir.

(Untuk konteksnya, saya sedang melacak perwakilan mingguan saya dengan sebuah skrip. Inilah bagian kode yang relevan dari skrip yang memungkinkan saya menghindari memukul Stack Overflow lebih dari sekali sehari untuk data yang sama.)

Pertama impor yang relevan:

from pathlib import Path
import tempfile

Kami tidak harus berurusan dengan os.path.joinsekarang - cukup gabungkan bagian-bagian jalur dengan /:

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

Lalu saya yakin memastikan direktori itu ada - exist_okargumen muncul di Python 3.5:

directory.mkdir(exist_ok=True)

Inilah bagian yang relevan dari dokumentasi :

Jika exist_okbenar, FileExistsErrorpengecualian akan diabaikan (perilaku yang sama dengan POSIX mkdir -pperintah), tetapi hanya jika komponen jalur terakhir bukan file non-direktori yang ada.

Berikut ini sedikit lebih banyak skrip - dalam kasus saya, saya tidak tunduk pada kondisi balapan, saya hanya memiliki satu proses yang mengharapkan direktori (atau file yang terkandung) berada di sana, dan saya tidak memiliki apa pun yang mencoba untuk menghapus direktori.

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

Pathobjek harus dipaksa strsebelum API lain yang mengharapkan strjalur dapat menggunakannya.

Mungkin Panda harus diperbarui untuk menerima contoh dari kelas dasar abstrak os.PathLike,.

Aaron Hall
sumber
20

Dalam Python 3.4 Anda juga dapat menggunakan modul barupathlib :

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.
Antti Haapala
sumber
@JanuszSkonieczny pypi.python.org/pypi/pathlib2 adalah backport yang lebih baru. Yang lebih tua tidak terawat.
Acumenus
Seperti yang dinyatakan dalam baris pertama readme; P. Namun backport lama masih berlaku untuk jawabannya di sini. Dan tidak ada penamaan sakit kepala. Tidak perlu menjelaskan mengapa dan kapan harus menggunakan pathlibdan di mana pathlib2untuk pengguna baru, dan saya pikir pro di sini akan mencari tahu penghentian;)
Janusz Skonieczny
13

The dokumentasi Python relevan menyarankan penggunaan EAFP pengkodean gaya (Mudah Minta Pengampunan dari Izin) . Ini artinya kodenya

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

lebih baik dari pada alternatif

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

Dokumentasi menyarankan ini tepat karena kondisi lomba yang dibahas dalam pertanyaan ini. Selain itu, seperti yang disebutkan orang lain di sini, ada keuntungan kinerja dalam meminta sekali daripada dua kali OS. Akhirnya, argumen yang diajukan, berpotensi, mendukung kode kedua dalam beberapa kasus - ketika pengembang tahu lingkungan aplikasi sedang berjalan - hanya dapat diadvokasi dalam kasus khusus bahwa program telah menyiapkan lingkungan pribadi untuk sendiri (dan contoh lain dari program yang sama).

Bahkan dalam kasus itu, ini adalah praktik yang buruk dan dapat menyebabkan proses debug yang lama dan tidak berguna. Misalnya, fakta bahwa kami mengatur izin untuk direktori tidak boleh meninggalkan kami dengan tayangan izin diatur dengan tepat untuk tujuan kami. Direktori induk dapat dipasang dengan izin lainnya. Secara umum, suatu program harus selalu bekerja dengan benar dan programmer tidak boleh mengharapkan satu lingkungan tertentu.

kavadias
sumber
11

Di Python3 , os.makedirsmendukung pengaturan exist_ok. Pengaturan default adalah False, yang berarti OSErrorakan dimunculkan jika direktori target sudah ada. Dengan mengatur exist_okke True, OSError(direktori ada) akan diabaikan dan direktori tidak akan dibuat.

os.makedirs(path,exist_ok=True)

Di Python2 , os.makedirstidak mendukung pengaturan exist_ok. Anda dapat menggunakan pendekatan ini dalam jawaban heikki-toivonen :

import os
import errno

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

Untuk solusi satu liner, Anda dapat menggunakan IPython.utils.path.ensure_dir_exists():

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

Dari dokumentasi : Pastikan direktori ada. Jika tidak ada, coba buat dan lindungi dari kondisi balapan jika proses lain melakukan hal yang sama.

tashuhka
sumber
Dokumentasi IPython baru tersedia di sini .
jkdev
3
The IPythonmodul benar-benar tidak dijamin untuk hadir. Ini secara asli hadir di Mac saya, tetapi tidak pada sembarang Linux saya menginstal Python. Pada dasarnya, ini bukan salah satu modul yang tercantum dalam Indeks Modul Python .
Acumenus
1
Tentu. Untuk menginstal paket, jalankan saja yang biasa pip install ipythonatau sertakan dependensi di requirement.txt atau pom.xml Anda . Dokumentasi: ipython.org/install.html
tashuhka
9

Kamu bisa menggunakan mkpath

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

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

Perhatikan bahwa itu akan membuat direktori leluhur juga.

Ini berfungsi untuk Python 2 dan 3.

Dennis Golomazov
sumber
2
distutils.dir_utilbukan bagian dari API publik distutil dan memiliki masalah di lingkungan multi-utas: bugs.python.org/issue10948
Pod
1
Iya. Seperti disebutkan dalam pesan pertama bug, masalahnya distutils.dir_util.mkpathadalah jika Anda membuat direktori, kemudian menghapusnya dari dalam atau di luar Python, kemudian gunakan mkpathlagi, mkpathcukup gunakan info cache yang tidak valid karena sebelumnya telah membuat direktori, dan akan sebenarnya tidak membuat direktori lagi. Sebaliknya, os.makedirstidak bergantung pada cache semacam itu.
Acumenus
8

Saya menggunakan os.path.exists(), di sini adalah skrip Python 3 yang dapat digunakan untuk memeriksa apakah direktori ada, buat satu jika tidak ada, dan hapus jika ada (jika diinginkan).

Ini meminta pengguna untuk input direktori dan dapat dengan mudah dimodifikasi.

Michael Strobel
sumber
6

Anda dapat menggunakan os.listdirini:

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')
iPhynx
sumber
Ini tidak menjawab pertanyaan
Georgy
6

Saya menemukan ini T / A dan saya awalnya bingung oleh beberapa kegagalan dan kesalahan yang saya dapatkan. Saya bekerja di Python 3 (v.3.5 di lingkungan virtual Anaconda pada sistem Linux x86_64 Arch).

Pertimbangkan struktur direktori ini:

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

Inilah eksperimen / catatan saya, yang menjelaskan berbagai hal:

# ----------------------------------------------------------------------------
# [1] /programming/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
# ----------------------------------------------------------------------------

Kesimpulan: menurut saya, "Metode 2" lebih kuat.

[1] Bagaimana saya bisa membuat direktori jika tidak ada?

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

Victoria Stuart
sumber
6

Saya melihat jawaban Heikki Toivonen dan ABB dan memikirkan variasi ini.

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
alissonmuller
sumber
6

Gunakan cek perintah ini dan buat dir

 if not os.path.isdir(test_img_dir):
     os.mkdir(test_img_dir)
Manivannan Murugavel
sumber
5

Mengapa tidak menggunakan modul subproses jika dijalankan pada mesin yang mendukung perintah mkdirdengan -popsi? Bekerja pada python 2.7 dan python 3.6

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

Sebaiknya lakukan trik pada kebanyakan sistem.

Dalam situasi di mana portabilitas tidak masalah (misalnya, menggunakan buruh pelabuhan) solusinya adalah 2 baris yang bersih. Anda juga tidak perlu menambahkan logika untuk memeriksa apakah direktori ada atau tidak. Akhirnya, aman untuk dijalankan kembali tanpa efek samping

Jika Anda perlu penanganan kesalahan:

from subprocess import check_call
try:
    check_call(['mkdir', '-p', 'path1/path2/path3'])
except:
    handle...
Geoff Paul Bremner
sumber
4

Jika Anda mempertimbangkan hal berikut:

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

berarti direktori (jalur) ada DAN adalah direktori. Jadi bagi saya cara ini melakukan apa yang saya butuhkan. Jadi saya bisa memastikan itu folder (bukan file) dan ada.

Ralph Schwerdt
sumber
Bagaimana ini menjawab pertanyaan membuat direktori?
Georgy
3

Panggil fungsi create_dir()di titik masuk program / proyek Anda.

import os

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

create_dir('Project directory')
Steffi Keran Rani J
sumber
3

Anda harus menetapkan path lengkap sebelum membuat direktori:

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)

Ini berfungsi untuk saya dan mudah-mudahan, itu akan bekerja untuk Anda juga

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

Di mana kode Anda di sini menggunakan perintah (sentuh)

Ini akan memeriksa apakah file ada di sana jika tidak maka akan membuatnya.

Ada yang Jahat
sumber