मैं पायथन में मूल निर्देशिका कैसे प्राप्त करूं?


350

क्या कोई मुझे बता सकता है कि क्रॉस प्लेटफ़ॉर्म रास्ते में पायथन में एक मार्ग की मूल निर्देशिका कैसे प्राप्त की जाए। उदाहरण के लिए

C:\Program Files ---> C:\

तथा

C:\ ---> C:\

यदि निर्देशिका में मूल निर्देशिका नहीं है, तो यह निर्देशिका को ही लौटाता है। प्रश्न सरल लग सकता है लेकिन मैं इसे Google के माध्यम से नहीं खोद सकता।

जवाबों:


481

पायथन 3.4 से अपडेट करें

pathlibमॉड्यूल का उपयोग करें ।

from pathlib import Path
path = Path("/here/your/path/file.txt")
print(path.parent)

पुराना उत्तर

इसे इस्तेमाल करे:

import os.path
print os.path.abspath(os.path.join(yourpath, os.pardir))

जहां yourpathपथ आप के लिए माता-पिता चाहते है।


137
आपका उत्तर सही है लेकिन दृढ़ है; os.path.dirnameइस के लिए समारोह है, की a+=5-4तुलना में अधिक जटिल है a+=1। प्रश्न केवल माता-पिता निर्देशिका का अनुरोध करता है, न कि मौजूद है या सही माता-पिता निर्देशिका को प्रतीकात्मक लिंक मानते हैं।
tzot

16
यह os.pardirनहीं है os.path.pardir
बुटीलेबलु

9
@bouteillebleu: दोनों os.pardirऔर os.path.pardirवास्तव में सही हैं (वे समान हैं)।
एरिक ओ लेबिगोट

45
@tzot: दुर्भाग्य os.path.dirnameसे अलग-अलग परिणाम देता है कि क्या पथ में एक अनुगामी स्लैश शामिल है। यदि आप विश्वसनीय परिणाम चाहते हैं तो आपको os.path.joinउत्तर में विधि का उपयोग करने की आवश्यकता है ।
आर्टफंकल

21
चूंकि यह स्पष्ट रूप से एक स्टैकऑवरफ्लो प्रश्न को वारंट करने के लिए पर्याप्त जटिल है, मुझे लगता है कि इसे एक अंतर्निहित फ़ंक्शन के रूप में ओएस.पाथ पुस्तकालय में जोड़ा जाना चाहिए।
antred

324

का उपयोग कर os.path.dirname:

>>> os.path.dirname(r'C:\Program Files')
'C:\\'
>>> os.path.dirname('C:\\')
'C:\\'
>>>

कैविएट: os.path.dirname()पथ में एक अनुगामी स्लैश शामिल है या नहीं इसके आधार पर अलग-अलग परिणाम देता है। यह वह शब्दार्थ हो सकता है जो आप चाहते हैं। सी एफ @ kender का उपयोग करके उत्तर os.path.join(yourpath, os.pardir)


6
os.path.dirname(r'C:\Program Files')क्या? पायथन सिर्फ आपको वह निर्देशिका दे रहा है जहाँ फ़ाइल 'प्रोग्राम फाइल्स' होगी। क्या अधिक है, यह भी मौजूद नहीं है, निहारना: os.path.dirname(r'c:\i\like\to\eat\pie')आउटपुट'c:\\i\\like\\to\\eat'
निक टी

41
मूल पोस्टर में यह नहीं बताया गया है कि निर्देशिका मौजूद है। बहुत सारे पाथनाम तरीके हैं जो स्ट्रिंग हेरफेर के अलावा कुछ नहीं करते हैं। यह सत्यापित करने के लिए कि क्या पथनाम वास्तव में मौजूद है, को डिस्क एक्सेस की आवश्यकता है। आवेदन पर निर्भर करता है कि यह वांछनीय हो सकता है या नहीं।
वाई वाई तुंग

10
यह समाधान os.sep अनुगामी के प्रति संवेदनशील है। ओस.सेप == '/' कहें। dirname (foo / bar) -> foo, लेकिन dirname (foo / bar /) -> foo / bar
marcin

6
वह डिजाइन द्वारा है। यह एक अनुगामी / के साथ एक मार्ग की व्याख्या के लिए नीचे आता है। क्या आप "path1" को "path1 /" के बराबर मानते हैं? पुस्तकालय सबसे सामान्य व्याख्या का उपयोग करते हैं कि वे अलग हैं। कुछ संदर्भों में लोग उन्हें समकक्ष मान सकते हैं। इस मामले में आप पहले एक rstrip ('/') कर सकते हैं। अगर पुस्तकालय दूसरी व्याख्या उठाता तो आप निष्ठा खो देते।
वाई वाई तुंग

3
@ रेयान, मैं उस बारे में नहीं जानता। URI में सापेक्ष पथ के मुद्दे को संबोधित करने के लिए एक संपूर्ण RFC 1808 लिखा गया है और सभी उपस्थिति और एक अनुगामी / अनुपस्थिति की सूक्ष्मता है। यदि आप किसी भी दस्तावेज के बारे में जानते हैं जो कहता है कि उन्हें सामान्य रूप से समतुल्य माना जाना चाहिए तो कृपया इसे इंगित करें।
वाई वाई तुंग

112

पैथलिब विधि (पायथन 3.4+)

from pathlib import Path
Path('C:\Program Files').parent
# Returns a Pathlib object

पारंपरिक विधि

import os.path
os.path.dirname('C:\Program Files')
# Returns a string


मुझे किस विधि का उपयोग करना चाहिए?

पारंपरिक विधि का उपयोग करें यदि:

  • यदि आप Pathlib ऑब्जेक्ट का उपयोग करते हैं तो आप मौजूदा कोड जनरेटिंग त्रुटियों के बारे में चिंतित हैं। (चूंकि पत्थलिब वस्तुओं को तार के साथ समतल नहीं किया जा सकता है।)

  • आपका पायथन संस्करण 3.4 से कम है।

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

यदि उपरोक्त में से कोई भी लागू नहीं होता है, तो Pathlib का उपयोग करें।



Pathlib क्या है?

यदि आप नहीं जानते कि Pathlib क्या है, तो Pathlib मॉड्यूल एक भयानक मॉड्यूल है जो आपके लिए फ़ाइलों के साथ काम करना भी आसान बनाता है। यदि सभी पायथन मॉड्यूल्स में निर्मित नहीं हैं, जो फाइलों के साथ काम करते हैं, तो वे पैथलिब ऑब्जेक्ट्स और स्ट्रिंग्स दोनों को स्वीकार करेंगे। मैंने Pathlib दस्तावेज़ीकरण के कुछ उदाहरणों के नीचे हाइलाइट किया है जो Pathlib के साथ आपके द्वारा की जाने वाली कुछ साफ-सुथरी चीज़ों का प्रदर्शन करते हैं।

निर्देशिका ट्री के अंदर नेविगेट करना:

>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
>>> q.resolve()
PosixPath('/etc/rc.d/init.d/halt')

पथ गुणों को छोड़ना:

>>> q.exists()
True
>>> q.is_dir()
False

4
यह एकमात्र समझदार जवाब है। यदि आप पायथन 2 का उपयोग करने के लिए मजबूर हैं, तो बस pip install pathlib2और बैकपोर्ट का उपयोग करें।
नविन

1
यह समाधान अनुगामी के लिए संवेदनशील नहीं है os.sep!
डायलन एफ

35
import os
p = os.path.abspath('..')

C:\Program Files ---> C:\\\

C:\ ---> C:\\\


7
यह केवल CWD के माता-पिता को मिलता है, न कि किसी अभिभावक के अभिभावक को, जैसा कि ओपी ने पूछा है।
सर्जियो

अपने URL के अंत में डबल डॉट्स जोड़ें और यह एग os.path.abspath(r'E:\O3M_Tests_Embedded\branches\sw_test_level_gp\test_scripts\..\..') रिजल्ट का काम करेगा :E:\\O3M_Tests_Embedded\\branches
अरिंदम रॉयचौधरी

इसका अर्थ है /:।
लोरेटोपरसी

26

@Kender का एक वैकल्पिक समाधान

import os
os.path.dirname(os.path.normpath(yourpath))

जहां yourpathपथ आप के लिए माता-पिता चाहते है।

लेकिन यह समाधान सही नहीं है, क्योंकि यह उस मामले को नहीं संभालेगा जहां yourpathएक खाली स्ट्रिंग, या एक डॉट है।

यह अन्य समाधान इस कोने के मामले को और अच्छी तरह से हैंडल करेगा:

import os
os.path.normpath(os.path.join(yourpath, os.pardir))

यहां हर मामले के लिए आउटपुट (इनपुट पथ सापेक्ष है) मिल सकता है:

os.path.dirname(os.path.normpath('a/b/'))          => 'a'
os.path.normpath(os.path.join('a/b/', os.pardir))  => 'a'

os.path.dirname(os.path.normpath('a/b'))           => 'a'
os.path.normpath(os.path.join('a/b', os.pardir))   => 'a'

os.path.dirname(os.path.normpath('a/'))            => ''
os.path.normpath(os.path.join('a/', os.pardir))    => '.'

os.path.dirname(os.path.normpath('a'))             => ''
os.path.normpath(os.path.join('a', os.pardir))     => '.'

os.path.dirname(os.path.normpath('.'))             => ''
os.path.normpath(os.path.join('.', os.pardir))     => '..'

os.path.dirname(os.path.normpath(''))              => ''
os.path.normpath(os.path.join('', os.pardir))      => '..'

os.path.dirname(os.path.normpath('..'))            => ''
os.path.normpath(os.path.join('..', os.pardir))    => '../..'

इनपुट पथ निरपेक्ष है (लिनक्स पथ):

os.path.dirname(os.path.normpath('/a/b'))          => '/a'
os.path.normpath(os.path.join('/a/b', os.pardir))  => '/a'

os.path.dirname(os.path.normpath('/a'))            => '/'
os.path.normpath(os.path.join('/a', os.pardir))    => '/'

os.path.dirname(os.path.normpath('/'))             => '/'
os.path.normpath(os.path.join('/', os.pardir))     => '/'

पथ को सामान्य करना हमेशा एक अच्छा अभ्यास होता है, खासकर जब क्रॉस-प्लेटफॉर्म काम करते हैं।
DevPlayer

यह सही जवाब है! यह सापेक्ष पथ को सापेक्ष बनाए रखता है। धन्यवाद!
मैक्सिम

@ मोमिन यह समाधान एकदम सही नहीं था, मैंने इसे सुधार लिया क्योंकि मूल समाधान एक मामले को नहीं संभालता है
बेंजारोबिन

@benjarobin हाँ, मैंने कोने के मामले के बारे में नहीं सोचा था। धन्यवाद।
मैक्सिम

18
os.path.split(os.path.abspath(mydir))[0]

यह उन रास्तों के लिए काम नहीं करेगा जो एक निर्देशिका के लिए हैं, यह सिर्फ निर्देशिका को फिर से लौटाएगा।
एंथनी ब्रिग्स

2
@AnthonyBriggs, मैंने सिर्फ Ubuntu 12.04 पर पायथन 2.7.3 का उपयोग करके यह कोशिश की और यह ठीक काम करने लगता है। उम्मीद के os.path.split(os.path.abspath("this/is/a/dir/"))[0]मुताबिक वापसी हुई '/home/daniel/this/is/a'। इस समय मेरे पास वहाँ चलने के लिए एक विंडोज़ बॉक्स नहीं है। आपने जो सेटअप रिपोर्ट की है, उस व्यवहार को आपने क्या देखा है?
डैन मेन

आप कर सकते थे parentdir = os.path.split(os.path.apspath(dir[:-1]))[0]। यह - मैं निश्चित हूं - काम करता है क्योंकि अगर अंत में एक स्लैश है, तो इसे हटा दिया जाता है; यदि कोई स्लैश नहीं है, तो यह अभी भी काम करेगा (भले ही पथ का अंतिम भाग केवल एक चार लंबा हो) पूर्ववर्ती स्लैश के कारण। यह निश्चित रूप से मानता है कि रास्ता उचित है और ऐसा कुछ नहीं कहना है /a//b/c///d////(यूनिक्स में यह अभी भी मान्य है), जो कि ज्यादातर मामलों में वे (उचित) विशेष रूप से तब होते हैं जब आप कुछ पसंद करते हैं os.path.abspathया कोई अन्य os.pathकार्य करते हैं।
dylnmc

इसके अलावा, अंत में बहुत सारे स्लैश का मुकाबला करने के लिए, आप लूप के लिए एक छोटा सा लिख ​​सकते हैं जो उन को हटा देता है। मुझे यकीन है कि ऐसा करने के लिए एक चतुर वन-लाइनर भी हो सकता है, या हो सकता है कि एक पंक्ति में os.path.split करें।
dylnmc

@ पुरुषों में मैंने सिर्फ आपको टिप्पणी करते देखा। यह काम नहीं करता है यदि आपके पास कुछ है os.path.split("a/b//c/d///")और उदाहरण के लिए, cd //////dev////// is equivalent to सीडी / देव / `या cd /dev; ये सभी लिनक्स में मान्य हैं। मैं अभी इसे लेकर आया हूं और यह उपयोगी हो सकता है, हालांकि os.path.split(path[:tuple(ind for ind, char in enumerate(path) if char != "/" and char != "\\")[-1]])[0]:। (यह अनिवार्य रूप से अंतिम गैर-स्लेश के लिए खोज करता है, और उस चार तक के मार्ग का विकल्प प्राप्त करता है।) मैंने उपयोग किया path = "/a//b///c///d////"और फिर पूर्वोक्त कथन चला '/a//b///c'
dylnmc


7
import os
print"------------------------------------------------------------"
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
print("example 1: "+SITE_ROOT)
PARENT_ROOT=os.path.abspath(os.path.join(SITE_ROOT, os.pardir))
print("example 2: "+PARENT_ROOT)
GRANDPAPA_ROOT=os.path.abspath(os.path.join(PARENT_ROOT, os.pardir))
print("example 3: "+GRANDPAPA_ROOT)
print "------------------------------------------------------------"

6

यदि आप केवल उस फ़ोल्डर का नाम चाहते हैं जो तर्क के रूप में प्रदान की गई फ़ाइल का तत्काल जनक है और उस फ़ाइल का पूर्ण पथ नहीं है :

os.path.split(os.path.dirname(currentDir))[1]

के currentDirमूल्य के साथ/home/user/path/to/myfile/file.ext

उपरोक्त आदेश वापस आ जाएगा:

myfile


3
os.path.basename (os.path.dirname (current_dir)) भी यहां काम करता है।
देवपल्ली २ Dev

4
>>> import os
>>> os.path.basename(os.path.dirname(<your_path>))

उदाहरण के लिए उबंटू में:

>>> my_path = '/home/user/documents'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'user'

विंडोज में उदाहरण के लिए:

>>> my_path = 'C:\WINDOWS\system32'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'WINDOWS'

दोनों उदाहरणों ने पायथन 2.7 में कोशिश की


3
import os.path

os.path.abspath(os.pardir)

यह माना जाता है कि आप "वर्तमान वर्किंग डायरेक्टरी" की मूल निर्देशिका चाहते हैं, न कि पेरेंट डायरेक्टरी की कोई भी राह।
DevPlayer

3

मान लीजिए कि हमारे पास निर्देशिका संरचना जैसी है

1]

/home/User/P/Q/R

हम निर्देशिका आर से "पी" के मार्ग का उपयोग करना चाहते हैं तब हम उपयोग कर सकते हैं

ROOT = os.path.abspath(os.path.join("..", os.pardir));

2]

/home/User/P/Q/R

हम निर्देशिका R से "Q" निर्देशिका के मार्ग का उपयोग करना चाहते हैं तब हम उपयोग कर सकते हैं

ROOT = os.path.abspath(os.path.join(".", os.pardir));

2

बस तुंग के जवाब में कुछ जोड़ना ( rstrip('/')यदि आप एक यूनिक्स बॉक्स पर हैं तो अधिक सुरक्षित होने का उपयोग करने की आवश्यकता है )।

>>> input = "../data/replies/"
>>> os.path.dirname(input.rstrip('/'))
'../data'
>>> input = "../data/replies"
>>> os.path.dirname(input.rstrip('/'))
'../data'

लेकिन, यदि आप उपयोग नहीं करते हैं rstrip('/'), तो आपका इनपुट दिया गया है

>>> input = "../data/replies/"

उत्पादन होगा,

>>> os.path.dirname(input)
'../data/replies'

जो संभवत: वह नहीं है जो आप देख रहे हैं जैसा आप दोनों चाहते हैं "../data/replies/"और "../data/replies"उसी तरह से व्यवहार करना चाहते हैं ।


1
मैं "इनपुट" को चर / संदर्भ के रूप में उपयोग नहीं करने की सलाह दूंगा। यह एक अंतर्निहित फ़ंक्शन है।
DevPlayer


1
print os.path.abspath(os.path.join(os.getcwd(), os.path.pardir))

आप अपनी py फ़ाइल के वर्तमान स्थान की मूल निर्देशिका प्राप्त करने के लिए इसका उपयोग कर सकते हैं।


2
यह सुझाव अक्सर बग की ओर जाता है। os.getcwd () अक्सर नहीं होता है जहां "आपकी py फ़ाइल" होती है। पैकेज सोचो। यदि मैं "some_package_with_subpackages" आयात करता हूं, तो कई मॉड्यूल उस पैकेज के शीर्ष-सबसे निर्देशिका में नहीं होंगे। os.getcwd () रिटर्न जहां आप शीर्ष-सर्वाधिक स्क्रिप्ट निष्पादित करते हैं। और यह भी मान लें कि आप इसे कमांड लाइन से कर रहे हैं।
DevPlayer

0

जनक निर्देशिका पथ प्राप्त करें और नई निर्देशिका (नाम) बनाएंnew_dir )

जनक निर्देशिका पथ प्राप्त करें

os.path.abspath('..')
os.pardir

उदाहरण 1

import os
print os.makedirs(os.path.join(os.path.dirname(__file__), os.pardir, 'new_dir'))

उदाहरण 2

import os
print os.makedirs(os.path.join(os.path.dirname(__file__), os.path.abspath('..'), 'new_dir'))


0
import os

def parent_filedir(n):
    return parent_filedir_iter(n, os.path.dirname(__file__))

def parent_filedir_iter(n, path):
    n = int(n)
    if n <= 1:
        return path
    return parent_filedir_iter(n - 1, os.path.dirname(path))

test_dir = os.path.abspath(parent_filedir(2))

0

ऊपर दिए गए उत्तर एक या दो निर्देशिका स्तरों के ऊपर जाने के लिए पूरी तरह से ठीक हैं, लेकिन अगर उन्हें निर्देशिका पेड़ को कई स्तरों (जैसे, 5 या 10) से पार करने की आवश्यकता हो, तो वे थोड़ा बोझिल हो सकते हैं। यह संक्षेप में N os.pardirs की सूची में शामिल होकर किया जा सकता है os.path.join। उदाहरण:

import os
# Create list of ".." times 5
upup = [os.pardir]*5
# Extract list as arguments of join()
go_upup = os.path.join(*upup)
# Get abspath for current file
up_dir = os.path.abspath(os.path.join(__file__, go_upup))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.