विंडोज पर पायथन ओ.एस.पी.


96

मैं अजगर को सीखने की कोशिश कर रहा हूं और एक कार्यक्रम बना रहा हूं जो एक स्क्रिप्ट का उत्पादन करेगा। मैं os.path.join का उपयोग करना चाहता हूं, लेकिन मैं बहुत भ्रमित हूं। डॉक्स के अनुसार अगर मैं कहूं:

os.path.join('c:', 'sourcedir')

मुझे मिला "C:sourcedir" । डॉक्स के अनुसार, यह सामान्य है, है ना?

लेकिन जब मैं कॉपिट्री कमांड का उपयोग करता हूं, तो पायथन इसे वांछित तरीके से आउटपुट करेगा, उदाहरण के लिए:

import shutil
src = os.path.join('c:', 'src')
dst = os.path.join('c:', 'dst')
shutil.copytree(src, dst)

यहाँ त्रुटि कोड मुझे मिलता है:

WindowsError: [त्रुटि 3] सिस्टम निर्दिष्ट पथ नहीं ढूँढ सकता: 'C: src /*.*'

अगर मैं os.path.joinसाथ लपेटता हूंos.path.normpath उसी त्रुटि हूं।

यदि यह os.path.join तरह से इसका उपयोग नहीं किया जा सकता है, तो मैं इसके उद्देश्य के रूप में भ्रमित हूं।

स्टैक ओवरफ्लो द्वारा सुझाए गए पृष्ठों के अनुसार, स्लैश का उपयोग ज्वाइन नहीं किया जाना चाहिए - यह सही है, मुझे लगता है?

जवाबों:


59

विंडोज में प्रत्येक ड्राइव के लिए वर्तमान निर्देशिका की अवधारणा है। उसके कारण,"c:sourcedir" वर्तमान C: निर्देशिका के अंदर "sourcedir" का अर्थ है, और आपको एक पूर्ण निर्देशिका निर्दिष्ट करने की आवश्यकता होगी।

इनमें से किसी को भी काम करना चाहिए और एक ही परिणाम देना चाहिए, लेकिन मेरे पास एक विंडोज़ वीएम नहीं है जो इस समय दोहरी जांच कर रहा है:

"c:/sourcedir"
os.path.join("/", "c:", "sourcedir")
os.path.join("c:/", "sourcedir")

8
os.path.join ('C: /', 'sourcedir') उम्मीद के मुताबिक काम किया। मैं आपको बहुत बहुत धन्यवाद सर :) दूसरों को '//' c: '' c: \\ 'काम नहीं किया (C: \\ दो backslashes बनाया, C: \ all काम नहीं किया) धन्यवाद फिर से ghostdog74 , स्मैशरी, और रोजर पटे। मैं आपके ऋण में हूँ :)
फ्रैंक ई।

क्षमा करें, लाइन ब्रेक को टिप्पणी में नहीं रखा गया था, यह बहुत ही गन्दा लगता है
फ्रैंक ई।

भले ही यह कुछ मामलों में काम करता है, @AndreasT द्वारा उत्तर एक बेहतर समाधान है। OS.sep ओएस के आधार पर / और \ के बीच चयन करेगा।
सेनहोरलुकास

क्या इसका उपयोग करने का कोई मतलब है os.path.joinया os.sepयदि आप c:वैसे भी निर्दिष्ट करने जा रहे हैं ? c:अन्य OS पर कोई मतलब नहीं है।
naught101

ये सभी समाधान केवल आंशिक रूप से संतोषजनक हैं। जब आपके पास एक विशिष्ट मामला है, तो मैन्युअल रूप से विभाजक जोड़ना ठीक है, लेकिन यदि आप इसे प्रोग्रामेटिक रूप से करना चाहते हैं, तो ऐसा कौन सा मानदंड है जिससे os.path.join('c:','folder')अलग तरीके से काम होता है os.path.join('folder','file')? क्या इसकी वजह से :या 'c: `एक ड्राइव है?
विंकेन्जुओ

121

और भी अधिक पांडित्यपूर्ण होने के लिए, सबसे अजगर डॉक्टर सुसंगत उत्तर होगा:

mypath = os.path.join('c:', os.sep, 'sourcedir')

चूँकि आपको पॉसिक्स रूट पथ के लिए os.sep की भी आवश्यकता है:

mypath = os.path.join(os.sep, 'usr', 'lib')

4
मेरी अज्ञानता का बहाना - ऐसा लगता है कि कोड अभी भी विंडोज और लिनक्स के बीच भिन्न होता है, तो क्या os.sepबेहतर बनाता है ?
पियानोजैम

3
कृपया इंजेक्शन लगाने का प्रयास करते समय इस स्नफ़ू पर ध्यान दें os.sep। यह केवल नंगे ड्राइव पत्र के बाद काम करता है। >>> os.path.join ("C: \ goodbye", os.sep, "temp") 'C: \\ temp'
Jobu

1
@pianoJames मेरा जवाब एक प्रणाली-अज्ञेय समाधान प्रदान करने के लिए इस एक का निर्माण करता है: stackoverflow.com/a/51276165/3996580
स्कॉट गिगांते

मुझे इन सभी "पांडित्य" समाधानों की बात समझ में नहीं आती है। os.sepजब आप विभाजक के बारे में धारणा बनाए बिना रास्तों में हेरफेर करना चाहते हैं तो उपयोगी है। इसका उपयोग करना व्यर्थ है os.path.join()क्योंकि यह पहले से ही सही विभाजक को जानता है। यदि आप नाम से मूल निर्देशिका को स्पष्ट रूप से निर्दिष्ट करना चाहते हैं, तो यह भी व्यर्थ है (जैसा कि आप अपने उदाहरण में देख सकते हैं)। क्यों "c:" + os.sepबजाय बस "c:\\", या os.sep + "usr"के बजाय बस "/usr"? यह भी ध्यान दें कि विन गोले में आप नहीं cd c:बल्कि आप यह cd c:\ बता सकते हैं कि मूल नाम वास्तव में है c:\
माइकल एकोका

13

कारण os.path.join('C:', 'src')यह काम नहीं कर रहा है क्योंकि आप अपेक्षा करते हैं कि आपके द्वारा जुड़े दस्तावेज़ में कुछ है:

ध्यान दें कि विंडोज पर, चूंकि प्रत्येक ड्राइव के लिए एक वर्तमान निर्देशिका है, os.path.join ("c:", "foo") ड्राइव C: (c: foo) पर वर्तमान निर्देशिका के सापेक्ष पथ का प्रतिनिधित्व करता है, c नहीं : \ foo।

जैसा कि घोस्टडॉग ने कहा, आप शायद चाहते हैं mypath=os.path.join('c:\\', 'sourcedir')


11

पांडित्यपूर्ण होने के लिए, पथ विभाजक के रूप में या तो / या \ _ हार्डकोड करना शायद अच्छा नहीं है। शायद यह सबसे अच्छा होगा?

mypath = os.path.join('c:%s' % os.sep, 'sourcedir')

या

mypath = os.path.join('c:' + os.sep, 'sourcedir')

11

एक सिस्टम-एग्नॉस्टिक सॉल्यूशन के लिए जो विंडोज और लिनक्स दोनों पर काम करता है, कोई फर्क नहीं पड़ता कि इनपुट रास्ता क्या है, कोई भी इस्तेमाल कर सकता है os.path.join(os.sep, rootdir + os.sep, targetdir)

पर:

>>> os.path.join(os.sep, "C:" + os.sep, "Windows")
'C:\\Windows'

लिनक्स पर:

>>> os.path.join(os.sep, "usr" + os.sep, "lib")
'/usr/lib'

1
धन्यवाद! यह और भी अधिक उपयोगी है क्योंकि यह उस गोच से पीड़ित नहीं है जो @Jobu ने पहले उल्लेख किया था: os.path.join (os.sep, "C: \\ a" + os.sep, "b") रिटर्न "C: विंडोज़ पर \\ a \\ b "।
पियानोजम्स

1
हालांकि इन दोनों में से कोई भी उदाहरण सिस्टम अज्ञेयवादी कैसे हैं? c:* nix पर मौजूद नहीं है, और usrविंडोज़ पर मौजूद नहीं है ..
naught101

फ़ंक्शन कॉल os.path.join(os.sep, rootdir + os.sep, targetdir)सिस्टम एग्नॉस्टिक है क्योंकि यह उन दोनों सिस्टम-विशिष्ट उदाहरणों के साथ काम करता है, कोड को बदलने की आवश्यकता के बिना।
स्कॉट गिगांटे

यह समाधान, पहले की पोस्ट की तरह, जिसने इसे प्रेरित किया, अभी भी रूटडिअर की तरह स्थापित करने पर निर्भर करता है rootdir = "usr" if nix else "c:"। लेकिन अधिक प्रत्यक्ष और सटीक rootdir = "/usr" if nix else "c:\\"काम करता है बस के रूप में अच्छी तरह से, os.sepकलाबाजी के बिना और सिर खरोंच के बिना । इसमें कोई खतरा नहीं है कि * nix पर एक रूट डाइरेक्टरी आगे के स्लैश के अलावा किसी भी चीज़ से शुरू होगी, या कि विंडोज के पास रूट डाइरेक्टर्स होंगे जिनका नाम एक अनुगामी बृहदान्त्र और बैकस्लैश के बिना होगा (जैसे विन गोले में, आप बस नहीं कर सकते cd c:, आप पीछे पीछे) को निर्दिष्ट करने की आवश्यकता है, इसलिए अन्यथा दिखावा क्यों करें?
माइकल एकोका

7

मैं कहूंगा कि यह एक (विंडोज़) अजगर बग है।

क्यों बग?

मुझे लगता है कि यह कथन होना चाहिए True

os.path.join(*os.path.dirname(os.path.abspath(__file__)).split(os.path.sep))==os.path.dirname(os.path.abspath(__file__))

लेकिन यह Falseविंडोज़ मशीनों पर है।


1
मैं सहमत हूँ कि एक अजगर बग का गठन करने के लिए इच्छुक हूं। क्या अभी भी यही मामला है? ( देर से 2015 के शानदार यूटोपियन भविष्य से लिखित। )
सेसिल करी

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

इसलिए मुझे वास्तव में इस सवाल के बारे में मेरा जवाब पसंद नहीं है। लेकिन मुझे इस बारे में अजगर का व्यवहार पसंद नहीं है।
जॉर्ज

@ क्या मैं इस प्रश्न पर अभी उसी मुद्दे की वजह से हूँ ... यह अभी भी मामला प्रतीत होता है।
जोशमॉड

5

एक विंडो पथ में शामिल होने के लिए, प्रयास करें

mypath=os.path.join('c:\\', 'sourcedir')

मूल रूप से, आपको स्लैश से बचने की आवश्यकता होगी


4

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

In[1]: from os.path import join, isdir

In[2]: from os import sep

In[3]: isdir(join("c:", "\\", "Users"))
Out[3]: True

In[4]: isdir(join("c:", "/", "Users"))
Out[4]: True

In[5]: isdir(join("c:", sep, "Users"))
Out[5]: True

0

@ जॉर्ज के साथ सहमति-

मैं तब कहूंगा कि हमें लंगड़े की आवश्यकता क्यों है os.path.join- बेहतर उपयोग str.joinया unicode.joinउदाहरण के लिए

sys.path.append('{0}'.join(os.path.dirname(__file__).split(os.path.sep)[0:-1]).format(os.path.sep))

2
हाँ, ठीक है, यह उस तरह से साफ है। जब आप उस पर हों तो रेगेक्स का उपयोग क्यों न करें? या एक पर्ल स्क्रिप्ट को कॉल करें और आउटपुट को प्रोसेस करें?
जीन फ़्राँस्वा Fabre

मुझे नहीं लगता कि यह एक अच्छा विचार है क्योंकि os.path.join बहुत अच्छा शब्दार्थ है ... इसलिए आप इसे एक कोड में देखते हैं और सीधे समझ जाते हैं कि क्या चल रहा है।
सेनहोरलुकास

0

आपकी टिप्पणी का उत्तर देते हुए: "द अन्य '//' c: ',' c: \\ 'काम नहीं किया (C: \\ ने दो बैकस्लैश बनाए, C: \ n बिल्कुल काम नहीं किया)"

खिड़कियों का उपयोग करने पर os.path.join('c:', 'sourcedir') स्वचालित रूप \\से sourcedir के सामने दो बैकस्लैश जोड़े जाएंगे

पथ को हल करने के लिए, चूंकि अजगर आगे की स्लैशों के साथ खिड़कियों पर भी काम करता है -> '/' , बस नीचे के .replace('\\','/')साथ जोड़ें os.path.join: -

os.path.join('c:\\', 'sourcedir').replace('\\','/')

उदाहरण के लिए: os.path.join('c:\\', 'temp').replace('\\','/')

आउटपुट: 'C: / अस्थायी'


0

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

थोड़ा प्रयोग करने के साथ, मेरा मानना ​​है कि मानदंड यह है कि पथ परिसीमन को नहीं जोड़ा गया है यदि पहला खंड एक ड्राइव अक्षर है, जिसका अर्थ है कि एक एकल अक्षर एक कोलन द्वारा पीछा किया जाता है, भले ही यह एक वास्तविक इकाई से मेल खाता हो।

उदाहरण के लिए:

import os
testval = ['c:','c:\\','d:','j:','jr:','data:']

for t in testval:
    print ('test value: ',t,', join to "folder"',os.path.join(t,'folder'))
test value:  c: , join to "folder" c:folder
test value:  c:\ , join to "folder" c:\folder
test value:  d: , join to "folder" d:folder
test value:  j: , join to "folder" j:folder
test value:  jr: , join to "folder" jr:\folder
test value:  data: , join to "folder" data:\folder

मानदंडों के लिए परीक्षण करने और पथ सुधार लागू करने का एक सुविधाजनक तरीका os.path.splitdriveपहले लौटे तत्व की तुलना परीक्षण मूल्य की तरह उपयोग करना हो सकता है t+os.path.sep if os.path.splitdrive(t)[0]==t else t

परीक्षा:

for t in testval:
    corrected = t+os.path.sep if os.path.splitdrive(t)[0]==t else t
    print ('original: %s\tcorrected: %s'%(t,corrected),' join corrected->',os.path.join(corrected,'folder'))
original: c:    corrected: c:\  join corrected-> c:\folder
original: c:\   corrected: c:\  join corrected-> c:\folder
original: d:    corrected: d:\  join corrected-> d:\folder
original: j:    corrected: j:\  join corrected-> j:\folder
original: jr:   corrected: jr:  join corrected-> jr:\folder
original: data: corrected: data:  join corrected-> data:\folder

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

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