मैं सुरक्षित रूप से नेस्टेड निर्देशिका कैसे बना सकता हूं?


4240

यह जांचने का सबसे सुरुचिपूर्ण तरीका है कि क्या निर्देशिका फ़ाइल को अस्तित्व में लिखा जा रहा है, और यदि नहीं, तो पायथन का उपयोग करके निर्देशिका बनाएं? यहाँ मैं कोशिश की है:

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)

किसी तरह, मैं चूक गया os.path.exists(धन्यवाद कंजा, ब्लेयर और डगलस)। मेरे पास अब यही है:

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

क्या "खुला" के लिए एक झंडा है, जो अपने आप ऐसा होता है?


27
सामान्य तौर पर आपको उस मामले के लिए खाते की आवश्यकता हो सकती है जहां फ़ाइलनाम में कोई निर्देशिका नहीं है। मेरी मशीन पर dirname ('foo.txt') '' देता है, जो मौजूद नहीं है और makedirs () को विफल करने का कारण बनता है।
ब्रायन हॉकिंस

11
अजगर में 2.7 os.path.mkdirमौजूद नहीं है। यह है os.mkdir
drevicko

6
यदि पथ मौजूद है, तो न केवल यह जांचने के लिए है कि यह एक निर्देशिका है और न ही एक नियमित फ़ाइल या कोई अन्य वस्तु (कई उत्तर इसकी जाँच करते हैं) यह जाँचने के लिए भी आवश्यक है कि क्या यह उपयुक्त है (मुझे ऐसा उत्तर नहीं मिला जिसने यह जाँच की हो)
चमत्कार 173

9
यदि आप फाइल पथ स्ट्रिंग की मूल निर्देशिका बनाने के लिए यहां आए हैं p, तो यहां मेरा कोड स्निपेट है:os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
थम्मे गौड़ा

जवाबों:


5182

पायथन, 3.5 पर, उपयोग करें pathlib.Path.mkdir:

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

पायथन के पुराने संस्करणों के लिए, मुझे अच्छे गुणों के साथ दो उत्तर दिखाई देते हैं, प्रत्येक में एक छोटा दोष है, इसलिए मैं इस पर अपना ध्यान दूंगा:

कोशिश करो os.path.exists, और os.makedirsनिर्माण के लिए विचार करें ।

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

जैसा कि टिप्पणियों और अन्य जगहों पर उल्लेख किया गया है, एक दौड़ की स्थिति है - यदि निर्देशिका कॉल os.path.existsऔर os.makedirsकॉल के बीच बनाई गई है , तो os.makedirsएक के साथ विफल हो जाएगी OSError। दुर्भाग्य से, कंबल-पकड़ने वालाOSError और जारी रखना मूर्खतापूर्ण नहीं है, क्योंकि यह अन्य कारकों, जैसे अपर्याप्त अनुमति, पूर्ण डिस्क, आदि के कारण निर्देशिका बनाने में विफलता को अनदेखा करेगा।

एक विकल्प यह होगा OSErrorकि एम्बेडेड त्रुटि कोड की जांच की जाए और ( पायथन के OSError से जानकारी प्राप्त करने का कोई क्रॉस-प्लेटफ़ॉर्म तरीका हो ):

import os, errno

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

वैकल्पिक रूप से, एक दूसरा हो सकता है os.path.exists, लेकिन मान लीजिए कि दूसरे ने पहले चेक के बाद निर्देशिका बनाई, फिर दूसरे से पहले इसे हटा दिया - हमें अभी भी बेवकूफ बनाया जा सकता है।

आवेदन के आधार पर, समवर्ती संचालन का खतरा फ़ाइल अनुमतियों जैसे अन्य कारकों द्वारा उत्पन्न खतरे से अधिक या कम हो सकता है। कार्यान्वयन को चुनने से पहले डेवलपर को विशेष रूप से विकसित किए जा रहे एप्लिकेशन और उसके अपेक्षित वातावरण के बारे में अधिक जानना होगा।

पायथन के आधुनिक संस्करण इस कोड में काफी सुधार करते हैं, दोनों को उजागर करके FileExistsError(3.3 + में) ...

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

... और अनुमति देकर किसी कीवर्ड को किसी तर्क os.makedirsकहा जाता हैexist_ok (3.2+ में)।

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

5
दौड़ की स्थिति एक अच्छा बिंदु है, लेकिन stackoverflow.com/questions/273192/#273208 में दृष्टिकोण , निर्देशिका बनाने में विफलता का सामना करेगा। नीचे मतदान के लिए बुरा मत मानना ​​- आपको जवाब पसंद नहीं है। यह वोट किस लिए हैं
ब्लेयर कॉनराड

27
याद रखें कि os.path.exists () निःशुल्क नहीं है। यदि सामान्य मामला यह है कि निर्देशिका वहां होगी, तो वह मामला जहां इसे अपवाद के रूप में नियंत्रित नहीं किया जाना चाहिए। दूसरे शब्दों में, अपनी फ़ाइल को खोलने और लिखने का प्रयास करें, OSError अपवाद को पकड़ें और इरनो के आधार पर, अपना makedir () करें और पुनः प्रयास करें या फिर से बढ़ाएँ। यह कोड का दोहराव तब तक बनाता है जब तक कि आप स्थानीय तरीके से लेखन को लपेटते नहीं हैं।
एंड्रयू

22
os.path.existsTrueएक फ़ाइल के लिए भी लौटता है । मैंने इसे संबोधित करने के लिए एक उत्तर पोस्ट किया है।
एक्यूमेनस

13
जैसा कि अन्य उत्तरों के लिए टिप्पणीकारों ने यहां उल्लेख किया है, exists_okपैरामीटर का os.makedirs()उपयोग यह कवर करने के लिए किया जा सकता है कि पायथन 3.2 के बाद से मार्ग का पूर्व अस्तित्व कैसे संभाला जाता है।
बोबले

6
os.mkdirs()यदि कोई पथ विभाजक गलती से छोड़ दिया जाता है तो अनपेक्षित फ़ोल्डर बना सकता है, वर्तमान फ़ोल्डर अपेक्षा के अनुरूप नहीं है, पथ तत्व में पथ विभाजक होता है। यदि आप os.mkdir()इन कीड़ों का उपयोग करते हैं, तो आप उनके अस्तित्व के लिए सतर्क करते हुए एक अपवाद उठाएंगे।
ड्रेविको जूल

1240

पायथन 3.5+:

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

pathlib.Path.mkdirजैसा कि ऊपर इस्तेमाल किया गया है, निर्देशिका को पुन: बनाता है और यदि निर्देशिका पहले से मौजूद है तो अपवाद नहीं बढ़ाता है। यदि आपको माता-पिता की आवश्यकता नहीं है या बनना चाहते हैं, तो छोड़ेंparents तर्क को ।

पायथन 3.2+:

का उपयोग कर pathlib:

यदि आप कर सकते हैं, तो वर्तमान में pathlibनामांकित बैकपोर्ट स्थापित करें pathlib2। नामांकित पुराने अप्रयुक्त बैकपोर्ट को स्थापित न करें pathlib। इसके बाद, ऊपर दिए गए पायथन 3.5+ सेक्शन को देखें और उसी का उपयोग करें।

यदि पायथन 3.4 का उपयोग किया जाता है, भले ही यह साथ आता है pathlib, लेकिन यह उपयोगी exist_okविकल्प को याद नहीं कर रहा है । बैकपोर्ट एक नए और बेहतर कार्यान्वयन की पेशकश करने का इरादा रखता है, mkdirजिसमें यह लापता विकल्प शामिल है।

का उपयोग कर os:

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

os.makedirsजैसा कि ऊपर इस्तेमाल किया गया है, निर्देशिका को पुन: बनाता है और यदि निर्देशिका पहले से मौजूद है तो अपवाद नहीं बढ़ाता है। exist_okडिफ़ॉल्ट मान के साथ, इसका केवल पाइथन 3.2+ का उपयोग करने पर वैकल्पिक तर्क हैFalse । यह तर्क पायथन 2.x में 2.7 तक मौजूद नहीं है। जैसे, पायथन 2.7 के साथ मैनुअल अपवाद हैंडलिंग की कोई आवश्यकता नहीं है।

पायथन 2.7+:

का उपयोग कर pathlib:

यदि आप कर सकते हैं, तो वर्तमान में pathlibनामांकित बैकपोर्ट स्थापित करें pathlib2। नामांकित पुराने अप्रयुक्त बैकपोर्ट को स्थापित न करें pathlib। इसके बाद, ऊपर दिए गए पायथन 3.5+ सेक्शन को देखें और उसी का उपयोग करें।

का उपयोग कर os:

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

जबकि एक भोला समाधान पहले उपयोग कर सकता os.path.isdirहै os.makedirs, ऊपर दिए गए समाधान दो संचालन के क्रम को उलट देता है। ऐसा करने में, यह निर्देशिका बनाने में एक डुप्लिकेट किए गए प्रयास के साथ एक सामान्य दौड़ की स्थिति को रोकता है, और निर्देशिकाओं के साथ फ़ाइलों को भी वितरित करता है।

ध्यान दें कि अपवाद को कैप्चर करना और उपयोग errnoकरना सीमित उपयोगिता का है OSError: [Errno 17] File exists, क्योंकि , errno.EEXISTफाइल और निर्देशिका दोनों के लिए उठाया जाता है। यह अधिक विश्वसनीय है कि निर्देशिका मौजूद है या नहीं।

वैकल्पिक:

mkpathनेस्टेड निर्देशिका बनाता है, और कुछ भी नहीं है अगर निर्देशिका पहले से मौजूद है। यह पायथन 2 और 3 दोनों में काम करता है।

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

प्रति बग 10948 , इस विकल्प की एक गंभीर सीमा यह है कि यह किसी दिए गए मार्ग के लिए केवल एक बार अजगर प्रक्रिया के अनुसार काम करता है। दूसरे शब्दों में, यदि आप एक निर्देशिका बनाने के लिए इसका उपयोग करते हैं, तो पायथन के अंदर या बाहर से निर्देशिका को हटा दें, फिर mkpathउसी निर्देशिका को फिर से बनाने के लिए फिर से उपयोग करें, mkpathबस चुपचाप अपनी अमान्य कैश्ड जानकारी का उपयोग पहले निर्देशिका बनाने के लिए करेंगे, और नहीं करेंगे वास्तव में फिर से निर्देशिका बनाते हैं। इसके विपरीत, os.makedirsइस तरह के किसी भी कैश पर भरोसा नहीं करता है। यह सीमा कुछ अनुप्रयोगों के लिए ठीक हो सकती है।


निर्देशिका के मोड के संबंध में , कृपया दस्तावेज का संदर्भ लें यदि आप इसकी परवाह करते हैं।


13
यह उत्तर बहुत विशेष रूप से हर विशेष मामले को कवर करता है जहाँ तक मैं बता सकता हूँ। मैं इसे "अगर नहीं os.path.isdir ()" में लपेटने की योजना बना रहा हूं, क्योंकि मुझे उम्मीद है कि निर्देशिका लगभग हर समय मौजूद रहेगी और मैं इस तरह से अपवाद से बच सकता हूं।
चार्ल्स एल।

5
@CharlesL। एक अपवाद शायद चेक के डिस्क आईओ से सस्ता है, यदि आपका कारण प्रदर्शन है।
jpmc26

1
@ jpmc26 लेकिन makedirs अतिरिक्त स्टेट, umask, lstat करते हैं जब केवल OSError को फेंकने के लिए जाँच की जाती है।
kwarunek

4
यह गलत उत्तर है, क्योंकि यह संभावित एफएस रेस कॉन्डेंस का परिचय देता है। हारून हॉल से जवाब देखें।
sleepycal

4
जैसा कि @sleepycal ने कहा है, यह स्वीकृत जवाब के समान रेस की स्थिति से ग्रस्त है। यदि त्रुटि को बढ़ाने और os.path.isdirकिसी अन्य व्यक्ति द्वारा फ़ोल्डर को हटाने के बीच, आप गलत, पुराना, और भ्रामक त्रुटि को बढ़ाएंगे जो फ़ोल्डर मौजूद है।
फ़ार्मर

604

इरानो मॉड्यूल से सही प्रयास और सही त्रुटि कोड का उपयोग करने से दौड़ की स्थिति से छुटकारा मिलता है और यह क्रॉस-प्लेटफॉर्म है:

import os
import errno

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

दूसरे शब्दों में, हम निर्देशिका बनाने की कोशिश करते हैं, लेकिन अगर वे पहले से मौजूद हैं तो हम त्रुटि को अनदेखा करते हैं। दूसरी ओर, किसी अन्य त्रुटि की सूचना मिलती है। उदाहरण के लिए, यदि आप पहले से dir 'a' बनाते हैं और उसमें से सभी अनुमतियां हटा देते हैं, तो आपको एक OSErrorउठाया हुआ errno.EACCES(अनुमति अस्वीकृत, त्रुटि 13) मिलेगा ।


24
स्वीकृत उत्तर वास्तव में खतरनाक है क्योंकि इसकी एक नस्ल-स्थिति है। हालांकि, यह आसान है, इसलिए यदि आप दौड़-हालत से अनजान हैं, या यह सोचते हैं कि यह आपके लिए लागू नहीं होगा, तो यह आपकी पहली पहली पसंद होगी।
हीकी टिवोनेन

15
अपवाद केवल तब exception.errno != errno.EEXISTउठाएं जब पथ मौजूद होने पर अनजाने में मामले को अनदेखा कर देगा, लेकिन एक गैर-निर्देशिका ऑब्जेक्ट जैसे कि फ़ाइल है। यदि पथ एक गैर-निर्देशिका ऑब्जेक्ट है, तो अपवाद को आदर्श रूप से उठाया जाना चाहिए।
एक्यूमेनस

178
ध्यान दें कि उपरोक्त कोडos.makedirs(path,exist_ok=True)
नवीन

58
@ नोविन exist_okपैरामीटर को पायथन 3.2 में पेश किया गया था। यह पाइथन 2.x में मौजूद नहीं है। मैं इसे अपने उत्तर में शामिल करूंगा।
एक्यूमेनस

26
@HeikkiToivonen तकनीकी रूप से, यदि कोई अन्य प्रोग्राम उसी समय निर्देशिकाओं और फ़ाइलों को संशोधित कर रहा है, तो आपका पूरा कार्यक्रम एक विशाल दौड़ की स्थिति है। कोड बनाने के बाद इस निर्देशिका को हटाने से पहले किसी अन्य प्रोग्राम को रोकने के लिए क्या है और इससे पहले कि आप वास्तव में इसमें फाइलें डालें?
jpmc26

102

मैं व्यक्तिगत रूप से अनुशंसा करूंगा कि आप os.path.isdir()इसके बजाय परीक्षण करने के लिए उपयोग करें 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

यदि आपके पास है:

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

और एक मूर्ख उपयोगकर्ता इनपुट:

:: /tmp/dirname/filename.etc

... आप filename.etcजब आप के os.makedirs()साथ परीक्षण करने के लिए उस तर्क को पारित जब नाम एक निर्देशिका के साथ समाप्त करने जा रहे हैं os.path.exists()


8
यदि आप केवल 'isdir' का उपयोग करते हैं, तो क्या आपको तब भी समस्या नहीं होगी जब आप निर्देशिका बनाने का प्रयास करते हैं और उसी नाम की फ़ाइल पहले से मौजूद है?
MrWonderful

3
@MrWonderful किसी मौजूदा फ़ाइल पर निर्देशिका बनाते समय परिणामी अपवाद कॉल करने वाले को समस्या को सही रूप से प्रतिबिंबित करेगा।
दामियन येरिक जूल

79

जाँच करें os.makedirs: (यह सुनिश्चित करता है कि पूरा पथ मौजूद है।)
इस तथ्य को संभालने के लिए कि निर्देशिका मौजूद हो सकती है, पकड़ें OSError। (यदि exist_okहै False(डिफ़ॉल्ट), तो एक OSErrorउठाया जाता है यदि लक्ष्य निर्देशिका पहले से मौजूद है।)

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

19
कोशिश के अलावा / छोड़कर, आप निर्देशिका निर्माण में त्रुटियों को मुखौटा करेंगे, उस स्थिति में जब निर्देशिका मौजूद नहीं थी, लेकिन किसी कारण से आप इसे नहीं बना सकते हैं
ब्लेयर कॉनराड

3
OSErrorयदि पथ मौजूदा फ़ाइल या निर्देशिका है, तो यहां उठाया जाएगा। मैंने इसे संबोधित करने के लिए एक उत्तर पोस्ट किया है।
एक्यूमेनस

4
यह वहाँ आधा है। OSErrorइसे अनदेखा करने का निर्णय लेने से पहले आपको उप-त्रुटि स्थिति की जांच करने की आवश्यकता है। देखें stackoverflow.com/a/5032238/763269
क्रिस जॉनसन

71

पायथन 3.5 से शुरू, pathlib.Path.mkdirएक 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)

यह पुनरावर्ती रूप से निर्देशिका बनाता है और यदि निर्देशिका पहले से मौजूद है, तो अपवाद नहीं बढ़ाता है।

(बस अजगर 3.2 से शुरू होने os.makedirsवाला एक exist_okझंडा मिला जैसे os.makedirs(path, exist_ok=True))


46

इस स्थिति की बारीकियों पर अंतर्दृष्टि

आप एक विशेष पथ पर एक विशेष फ़ाइल देते हैं और आप फ़ाइल पथ से निर्देशिका खींचते हैं। फिर यह सुनिश्चित करने के बाद कि आपके पास निर्देशिका है, आप पढ़ने के लिए एक फ़ाइल खोलने का प्रयास करते हैं। इस कोड पर टिप्पणी करने के लिए:

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

हम बिल्टइन फंक्शन को ओवर राइट करने से बचना चाहते हैं dir। इसके अलावा, filepathया शायद fullfilepathशायद एक बेहतर शब्दार्थ नाम है, filenameइसलिए यह बेहतर लिखा जाएगा:

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

आपका अंतिम लक्ष्य इस फ़ाइल को खोलना है, आप शुरू में लिखते हैं, लेकिन आप अनिवार्य रूप से इस लक्ष्य (अपने कोड के आधार पर) को इस तरह से प्राप्त कर रहे हैं, जो पढ़ने के लिए फ़ाइल खोलता है :

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

पढ़ने के लिए उद्घाटन मानते हुए

आप एक ऐसी फ़ाइल के लिए एक निर्देशिका क्यों बनाएंगे जिसकी आप उम्मीद करते हैं कि वह वहां हो और पढ़ने में सक्षम हो?

बस फ़ाइल को खोलने का प्रयास करें।

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

यदि निर्देशिका या फ़ाइल नहीं है, तो आपको IOErrorएक संबद्ध त्रुटि संख्या errno.ENOENTमिलेगी : आपके प्लेटफ़ॉर्म की परवाह किए बिना सही त्रुटि संख्या की ओर इशारा करेगी। आप इसे पकड़ सकते हैं यदि आप चाहें, उदाहरण के लिए:

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

यह मानते हुए कि हम लेखन के लिए खोल रहे हैं

यह वह जगह है शायद तुम क्या चाहते हो।

इस मामले में, हम शायद किसी भी दौड़ की स्थिति का सामना नहीं कर रहे हैं। इसलिए जैसा आप थे वैसा ही करें, लेकिन ध्यान दें कि लिखने के लिए, आपको wमोड (या aअपेंड) के साथ ओपन करना होगा । फ़ाइलों को खोलने के लिए संदर्भ प्रबंधक का उपयोग करना भी पायथन का सबसे अच्छा अभ्यास है।

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

हालाँकि, मान लें कि हमारे पास कई पायथन प्रक्रियाएँ हैं जो अपने सभी डेटा को एक ही डायरेक्टरी में रखने का प्रयास करती हैं। फिर निर्देशिका के निर्माण पर हमारा विवाद हो सकता है। उस मामले में makedirsकॉल को छोड़कर एक कोशिश ब्लॉक में लपेटना सबसे अच्छा है ।

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)

34

os.path.existsफ़ंक्शन का प्रयास करें

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

3
मैं इस प्रश्न पर टिप्पणी करने जा रहा था, लेकिन क्या हमारा मतलब ऑस्मकदिर से है? मेरे अजगर (2.5.2) का कोई os.path.mkdir नहीं है ...
ब्लेयर कॉनरैड

1
कोई os.path.mkdir()विधि नहीं है। os.path मॉड्यूल पाथनाम पर कुछ उपयोगी कार्यों को कार्यान्वित करता है
सर्ज एस

31

मैंने नीचे लिखा है। हालांकि यह पूरी तरह से मूर्ख नहीं है।

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

अब जैसा कि मैं कहता हूं, यह वास्तव में मूर्खतापूर्ण नहीं है, क्योंकि हमारे पास निर्देशिका बनाने में विफल रहने की क्षमता है, और उस अवधि के दौरान इसे बनाने की एक और प्रक्रिया है।



दो समस्याएं: (1) आपको जांच करने का निर्णय लेने से पहले OSError की उप-त्रुटि स्थिति की जांच करने की आवश्यकता है os.path.exists- देखें stackoverflow.com/a/5032238/763269, और (2) सफलता का os.path.existsमतलब यह नहीं है कि निर्देशिका मौजूद है, बस पथ मौजूद - एक फ़ाइल, या एक सिमलिंक, या अन्य फ़ाइल सिस्टम ऑब्जेक्ट हो सकता है।
क्रिस जॉनसन

24

जाँच करें कि क्या कोई निर्देशिका मौजूद है और यदि आवश्यक हो तो इसे बनाएं?

इसका सीधा उत्तर यह है कि एक साधारण स्थिति मानकर जहां आप अन्य उपयोगकर्ताओं या प्रक्रियाओं को अपनी निर्देशिका के साथ खिलवाड़ करने की उम्मीद नहीं करते हैं:

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

या अगर निर्देशिका बनाना दौड़ की स्थिति के अधीन है (यानी यदि पथ की जाँच के बाद मौजूद है, तो कुछ और पहले से ही हो सकता है) ऐसा करें:

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

लेकिन संभवत: एक बेहतर तरीका यह है कि अस्थाई निर्देशिकाओं के माध्यम से संसाधन विवाद मुद्दे को दरकिनार किया जाए tempfile:

import tempfile

d = tempfile.mkdtemp()

यहाँ ऑनलाइन डॉक्टर से आवश्यक है:

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.

पायथन 3.5 में नया: के pathlib.Pathसाथexist_ok

एक नई Pathवस्तु है (3.4 के रूप में) बहुत सारे तरीकों के साथ एक पथ के साथ उपयोग करना चाहेगा - जिनमें से एक है mkdir

(संदर्भ के लिए, मैं एक स्क्रिप्ट के साथ अपने साप्ताहिक प्रतिनिधि को ट्रैक कर रहा हूं। यहां स्क्रिप्ट से कोड के प्रासंगिक हिस्से हैं जो मुझे एक ही डेटा के लिए दिन में एक से अधिक बार स्टैक ओवरफ्लो से बचने की अनुमति देते हैं।)

पहले प्रासंगिक आयात:

from pathlib import Path
import tempfile

हमें os.path.joinअब इससे निपटने की जरूरत नहीं है - बस एक के साथ पथ भागों में शामिल हों /:

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

तब मैं यह सुनिश्चित करता हूं कि निर्देशिका मौजूद है - यह exist_okतर्क पायथन 3.5 में दिखाया गया है:

directory.mkdir(exist_ok=True)

यहाँ प्रलेखन का प्रासंगिक हिस्सा है :

यदि exist_okसत्य है, तो FileExistsErrorअपवादों को अनदेखा किया जाएगा ( POSIX mkdir -pकमांड के रूप में एक ही व्यवहार ), लेकिन केवल अगर अंतिम पथ घटक मौजूदा गैर-निर्देशिका फ़ाइल नहीं है।

यहां स्क्रिप्ट की थोड़ी अधिक जानकारी है - मेरे मामले में, मैं एक दौड़ की स्थिति के अधीन नहीं हूं, मेरे पास केवल एक प्रक्रिया है जो निर्देशिका (या निहित फ़ाइलों) की अपेक्षा करती है, और मेरे पास हटाने की कोई कोशिश नहीं है निर्देशिका।

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वस्तुओं को strअन्य एपीआई से पहले ज़ब्त करना पड़ता है जो उम्मीद करते हैं कि strपथ उनका उपयोग कर सकते हैं।

शायद पंडों को अमूर्त आधार वर्ग के उदाहरणों को स्वीकार करने के लिए अद्यतन किया जाना चाहिए os.PathLike


20

पायथन 3.4 में आप ब्रांड के नए 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.

@JanuszSkonieczny pypi.python.org/pypi/pathlib2 नया पासपोर्ट है। बड़ा पुराना है।
एक्यूमेनस

जैसा कि यह रीडमी की पहली पंक्ति में कहा गया है; पी। लेकिन पुराना बैकपोर्ट अभी भी यहां उत्तर के लिए मान्य है। और सिर दर्द का नामोनिशान नहीं है। नए उपयोगकर्ताओं के लिए क्यों और कब pathlibऔर कहाँ उपयोग करना है pathlib2, और मुझे समझाने की आवश्यकता नहीं है , और मुझे लगता है कि यहाँ पेशेवरों को पदावनति का पता चलेगा;)
Janusz Skonieczny

13

प्रासंगिक अजगर प्रलेखन के उपयोग का सुझाव शैली कोडिंग (आसान अनुमति से माफी के लिए पूछें करने के लिए) EAFP । इसका मतलब है कि कोड

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

विकल्प से बेहतर है

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

प्रलेखन इस सवाल में चर्चा की दौड़ की स्थिति के कारण बिल्कुल सुझाव देता है। इसके अतिरिक्त, जैसा कि अन्य लोग यहाँ उल्लेख करते हैं, ओएस के दो बार के बजाय एक बार क्वेरी करने में प्रदर्शन लाभ है। अंत में, तर्क को आगे रखा गया, संभवतः, कुछ मामलों में दूसरे कोड के पक्ष में - जब डेवलपर को पता चल रहा है कि एप्लिकेशन चल रहा है - तो केवल उस विशेष मामले में वकालत की जा सकती है जो प्रोग्राम ने एक निजी वातावरण स्थापित किया है खुद (और एक ही कार्यक्रम के अन्य उदाहरण)।

उस मामले में भी, यह एक बुरा अभ्यास है और लंबे समय तक बेकार डिबगिंग का कारण बन सकता है। उदाहरण के लिए, एक निर्देशिका के लिए अनुमतियों को सेट करने वाले तथ्य को हमें हमारे उद्देश्यों के लिए उचित रूप से निर्धारित की गई अनुमति के साथ नहीं छोड़ना चाहिए। एक पेरेंट डायरेक्टरी को अन्य अनुमतियों के साथ रखा जा सकता है। सामान्य तौर पर, एक प्रोग्राम को हमेशा सही ढंग से काम करना चाहिए और प्रोग्रामर को एक विशिष्ट वातावरण की उम्मीद नहीं करनी चाहिए।


11

में python3 , os.makedirsका समर्थन करता है की स्थापना exist_ok। डिफ़ॉल्ट सेटिंग है False, जिसका अर्थ है कि OSErrorअगर लक्ष्य निर्देशिका पहले से मौजूद है तो उठाया जाएगा। की स्थापना करके exist_okकरने के लिए True, OSError(निर्देशिका मौजूद है) नजरअंदाज कर दिया जाएगा और निर्देशिका नहीं बनाया जाएगा।

os.makedirs(path,exist_ok=True)

में को Python2 , os.makedirsसेटिंग का समर्थन नहीं करता exist_ok। आप 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

11

एक-लाइनर समाधान के लिए, आप उपयोग कर सकते हैं IPython.utils.path.ensure_dir_exists():

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

से प्रलेखन : सुनिश्चित करें कि एक निर्देशिका मौजूद है। यदि यह मौजूद नहीं है, तो इसे बनाने की कोशिश करें और दौड़ की स्थिति से बचाव करें यदि कोई अन्य प्रक्रिया समान है।


यहाँ उपलब्ध नया आईपाइथन प्रलेखन ।
jkdev

3
IPythonमॉड्यूल पूरी तरह से उपस्थित रहने की गारंटी नहीं है। यह मूल रूप से मेरे मैक पर मौजूद है, लेकिन पायथन के मेरे किसी भी लिनक्स पर नहीं। मूल रूप से, यह पायथन मॉड्यूल इंडेक्स में सूचीबद्ध मॉड्यूल में से एक नहीं है ।
एक्यूमेनस

1
ज़रूर। आदेश पैकेज स्थापित करने के लिए, बस हमेशा की तरह चलाने के pip install ipythonलिए या अपने में निर्भरता शामिल requirements.txt या pom.xml । प्रलेखन: ipython.org/install.html
tashuhka

9

आप उपयोग कर सकते हैं mkpath

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

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

ध्यान दें कि यह पूर्वज निर्देशिकाओं को भी बनाएगा।

यह पायथन 2 और 3 के लिए काम करता है।


2
distutils.dir_utilडिस्टुटिल पब्लिक एपीआई का एक हिस्सा नहीं है और इसमें बहु थ्रेडेड वातावरण में समस्याएं हैं: bugs.python.org/issue10948
पॉड

1
हाँ। जैसा कि बग के पहले संदेश में उल्लेख किया गया है , समस्या distutils.dir_util.mkpathयह है कि यदि आप एक निर्देशिका बनाते हैं, तो इसे पायथन के अंदर या बाहर से हटा दें, फिर mkpathदोबारा उपयोग करें, mkpathबस पहले से बनाई गई निर्देशिका को बनाने की अपनी अमान्य कैश्ड जानकारी का उपयोग करेंगे, और करेंगे वास्तव में फिर से निर्देशिका नहीं बनाते हैं। इसके विपरीत, os.makedirsइस तरह के किसी भी कैश पर भरोसा नहीं करता है।
एक्यूमेनस

8

मैं उपयोग करता हूं os.path.exists(), यहां एक पायथन 3 स्क्रिप्ट है जिसका उपयोग यह जांचने के लिए किया जा सकता है कि क्या कोई निर्देशिका मौजूद है, एक मौजूद है यदि यह मौजूद नहीं है और यदि मौजूद है तो इसे हटा दें (यदि वांछित है)।

यह उपयोगकर्ताओं को निर्देशिका के इनपुट के लिए संकेत देता है और इसे आसानी से संशोधित किया जा सकता है।


6

आप इसके लिए उपयोग कर सकते हैं os.listdir:

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

इस सवाल का जवाब नहीं है
Georgy

6

मुझे यह क्यू / ए मिला और मैं शुरू में कुछ असफलताओं और त्रुटियों से हैरान था। मैं पायथन 3 (एक आर्क लिनक्स x86_64 सिस्टम पर एनाकोंडा आभासी वातावरण में v.3.5) पर काम कर रहा हूं।

इस निर्देशिका संरचना पर विचार करें:

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

यहां मेरे प्रयोग / नोट हैं, जो चीजों को स्पष्ट करते हैं:

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

निष्कर्ष: मेरी राय में, "विधि 2" अधिक मजबूत है।

[१] मैं एक निर्देशिका कैसे बना सकता हूँ यदि यह मौजूद नहीं है?

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


6

मैंने हिकी टिवोनन और एबीबी के उत्तर देखे और इस भिन्नता के बारे में सोचा।

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


5

यदि विकल्प के mkdirसाथ कमांड का समर्थन करने वाली मशीन पर चल रहा है तो सबप्रोसेस मॉड्यूल का उपयोग क्यों नहीं करें -p? अजगर 2.7 और अजगर 3.6 पर काम करता है

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

अधिकांश सिस्टम पर चाल चलनी चाहिए।

उन स्थितियों में जहां पोर्टेबिलिटी कोई फर्क नहीं पड़ता (उदाहरण के लिए, docker का उपयोग करके) समाधान एक साफ 2 लाइनें है। यदि निर्देशिका मौजूद है या नहीं, तो आपको यह जांचने के लिए तर्क जोड़ने की आवश्यकता नहीं है। अंत में, बिना किसी साइड इफेक्ट के इसे फिर से चलाना सुरक्षित है

यदि आपको त्रुटि से निपटने की आवश्यकता है:

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

4

यदि आप निम्नलिखित पर विचार करते हैं:

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

एक निर्देशिका (पथ) मौजूद है और एक निर्देशिका है। तो मेरे लिए यह तरीका वही है जो मुझे चाहिए। इसलिए मैं यह सुनिश्चित कर सकता हूं कि यह फ़ोल्डर है (फ़ाइल नहीं) और मौजूद है।


यह एक निर्देशिका बनाने के सवाल का जवाब कैसे देता है ?
जॉर्जी

3

create_dir()अपने कार्यक्रम / परियोजना के प्रवेश बिंदु पर फ़ंक्शन को कॉल करें ।

import os

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

create_dir('Project directory')

3

निर्देशिका बनाने से पहले आपको पूर्ण पथ सेट करना होगा:

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)

यह मेरे लिए काम करता है और उम्मीद है, यह आपके लिए भी काम करेगा


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

जहां आपका कोड यहां (टच) कमांड का उपयोग कर रहा है

यह जांच करेगा कि अगर फ़ाइल वहां है अगर यह नहीं है तो वह इसे बनाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.