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




exception path (20)

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

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

यह जांचने का सबसे शानदार तरीका क्या है कि निर्देशिका में मौजूद एक निर्देशिका मौजूद है या नहीं, और यदि नहीं, तो Python का उपयोग कर निर्देशिका बनाएं? मैंने जो कोशिश की है वह यहां है:

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)

क्या "खुला" के लिए कोई झंडा है, जो यह स्वचालित रूप से होता है?


पायथन 3.5+:

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

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

पायथन 3.2+:

pathlib का उपयोग करना:

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

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

os का उपयोग करना:

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

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

पायथन 2.7+:

pathlib का उपयोग करना:

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

os का उपयोग करना:

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

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

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

वैकल्पिक:

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

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

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

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


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

जहां आपका कोड यहां (स्पर्श) कमांड का उपयोग करता है

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


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

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

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


आप 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 के लिए काम करता है।


मैं व्यक्तिगत रूप से अनुशंसा करता हूं कि os.path.isdir() का उपयोग os.path.isdir() के बजाय परीक्षण करने के लिए करें।

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

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


पायथन 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)

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

(जैसे os.makedirs को python 3.2 से शुरू होने वाला एक exists_ok ध्वज मिला है)।


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

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


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

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

फ़ाइल I / O के साथ काम करते समय, विचार करने की महत्वपूर्ण बात यह है कि

टॉक्टू (उपयोग के समय की जांच का समय)

तो ifबाद में चेक करना और फिर पढ़ना या लिखना एक अनचाहे I / O अपवाद में समाप्त हो सकता है। ऐसा करने का सबसे अच्छा तरीका है:

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

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

इस स्थिति के विनिर्देशों पर अंतर्दृष्टि

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

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)

यदि निर्देशिका या फ़ाइल नहीं है, तो आपको एक संबंधित त्रुटि संख्या के साथ errno.ENOENT मिलेगा: 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 को लपेटने के लिए सबसे अच्छा 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)

शेल भाषाओं का समर्थन करने वाली मशीन पर चलने पर उपप्रोसेसर मॉड्यूल का उपयोग क्यों न करें? पायथन 2.7 और पायथन 3.6 पर काम करता है

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

अधिकांश प्रणालियों पर चाल करना चाहिए।


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

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

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


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

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

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

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


पायथन 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.

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

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

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 साथ

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

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

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

from pathlib import Path
import tempfile

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

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

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

directory.mkdir(exist_ok=True)

pathlib.Path.mkdir का प्रासंगिक हिस्सा यहां दिया गया pathlib.Path.mkdir :

यदि 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 को अमूर्त बेस क्लास, os.PathLikeos.PathLike उदाहरणों को स्वीकार करने के लिए अद्यतन किया जाना चाहिए।


मैंने हेइककी टिवोनन और share के जवाब और इस बदलाव के बारे में सोचा।

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

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

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

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


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

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 नहीं है, क्योंकि यह अन्य कारकों के कारण निर्देशिका बनाने में विफलता को अनदेखा कर देगा, जैसे अपर्याप्त अनुमतियां, पूर्ण डिस्क इत्यादि।

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

import os, errno

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

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

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





operating-system