क्या मुझे `import os.path` या` import os` का उपयोग करना चाहिए?


139

आधिकारिक दस्तावेज के अनुसार , os.pathएक मॉड्यूल है। इस प्रकार, इसे आयात करने का पसंदीदा तरीका क्या है?

# Should I always import it explicitly?
import os.path

या ...

# Is importing os enough?
import os

कृपया जवाब न osदें "मेरे लिए आयात काम करता है"। मुझे पता है, यह अभी मेरे लिए भी काम करता है (पाइथन 2.6 के रूप में)। मैं इस मुद्दे के बारे में कोई आधिकारिक सिफारिश जानना चाहता हूं। इसलिए, यदि आप इस प्रश्न का उत्तर देते हैं, तो कृपया अपने संदर्भ पोस्ट करें

जवाबों:


157

os.pathमजाकिया तरीके से काम करता है। ऐसा लगता है कि osएक सबमॉड्यूल के साथ एक पैकेज होना चाहिए path, लेकिन वास्तव osमें एक सामान्य मॉड्यूल है जो sys.modulesइंजेक्शन के साथ जादू करता है os.path। यहाँ क्या होता है:

  • जब पायथन शुरू होता है, तो यह मॉड्यूल का एक गुच्छा लोड करता है sys.modules। वे आपकी स्क्रिप्ट में किसी भी नाम के लिए बाध्य नहीं हैं, लेकिन जब आप किसी तरह से आयात करते हैं तो आप पहले से ही बनाए गए मॉड्यूल तक पहुंच सकते हैं।

    • sys.modulesएक तानाशाही है जिसमें मॉड्यूल को कैश किया जाता है। जब आप किसी मॉड्यूल को आयात करते हैं, अगर यह पहले से ही कहीं आयात किया गया है, तो इसे अंदर संग्रहीत उदाहरण मिलता है sys.modules
  • osउन मॉड्यूलों में से एक है जो पाइथन शुरू होने पर लोड होते हैं। यह pathएक ओएस-विशिष्ट पथ मॉड्यूल के लिए अपनी विशेषता प्रदान करता है ।

  • यह इंजेक्ट करता है sys.modules['os.path'] = pathताकि आप " import os.path" कर सकें क्योंकि यह एक सबमॉड्यूल था।

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


संयोग से, इस तरह की संरचना बहुत सारे पायथन प्रोग्रामर के मॉड्यूल और पैकेज और कोड संगठन के बारे में शुरुआती भ्रम की ओर ले जाती है, मुझे लगता है। यह वास्तव में दो कारणों से है

  1. यदि आप osएक पैकेज के रूप में सोचते हैं और जानते हैं कि आप कर सकते हैं import osऔर सबमॉड्यूल तक पहुंच सकते हैं os.path, तो आप बाद में आश्चर्यचकित हो सकते हैं जब आप ऐसा नहीं कर सकते हैं import twistedऔर स्वचालित रूप से twisted.spreadइसे आयात किए बिना पहुंच सकते हैं ।

  2. यह भ्रामक है कि os.nameएक सामान्य बात है, एक स्ट्रिंग है, और os.pathएक मॉड्यूल है। मैं हमेशा अपने पैकेज को खाली __init__.pyफाइलों के साथ संरचना करता हूं ताकि उसी स्तर पर मेरे पास हमेशा एक प्रकार की चीज हो: एक मॉड्यूल / पैकेज या अन्य सामान। कई बड़े पायथन प्रोजेक्ट इस दृष्टिकोण को अपनाते हैं, जो अधिक संरचित कोड बनाने के लिए जाता है।


बहुत बढ़िया, बहुत जानकारीपूर्ण उत्तर! बधाई हो! भले ही यह सीधे सवाल का जवाब नहीं देता है, लेकिन इसमें बहुत सारे उपयोगी विवरण हैं। लेकिन क्या आप इस बारे में विस्तार से बता सकते हैं कि "यह कैसे संगत है। ओसपथ को कैसे प्रलेखित किया गया है"? जैसे क्रिस हुलन ने कहा, os.walk () उदाहरण os.path के बजाय केवल os आयात करता है।
डेनिलसन सिया मिया

3
@ डाइनिलसन, इसमें एक सीधा उत्तर शामिल है: मैं हमेशा import os.pathखुद को करता हूं और सोचता हूं कि यह एक अच्छा तरीका है। "यह इस बात के अनुरूप है कि os.path को किस तरह से प्रलेखित किया गया है" मेरा मतलब था कि इसे दस्तावेज़ में docs.python.org/library/os.path.html पर अपना पेज दिया गया है ।
माइक ग्राहम

1
वाह, os.pyवास्तव में इंजेक्ट करता है sys.modules['os.path']। इसलिए यह from os.path import somethingवास्तव में काम करता है। मैं इस बारे में उत्सुक था कि यह कब पेश किया गया और स्रोत की जाँच की गई। मजेदार तथ्य: यह 1999 से है, पहली बार पायथन 1.5.2 में शामिल किया गया। मूल वचन यहाँ है
ब्लूहॉर्न

29

के अनुसार पीईपी -20 टिम पीटर्स द्वारा, और "पठनीयता मायने रखता है" "स्पष्ट निहित की तुलना में बेहतर है।" यदि आपको osमॉड्यूल से सभी की जरूरत है os.path, import os.pathतो यह अधिक स्पष्ट होगा और दूसरों को बताएंगे कि आप वास्तव में क्या परवाह करते हैं।

इसी तरह, PEP-20 भी कहता है, "सिंपल कॉम्प्लेक्स से बेहतर है", इसलिए यदि आपको ऐसे सामान की भी ज़रूरत है जो अधिक सामान्य osछतरी के नीचे रहता है, import osतो उसे प्राथमिकता दी जाएगी।


2
मैं नहीं देखता कि import osकिसी भी सार्थक तरीके से "सरल" होने के बारे में वास्तव में कैसा है। सरल! = संक्षिप्त।
माइक ग्राहम

14
मैं और अधिक करते रहे कि कोशिश कर रहा था import os और एक import os.pathअगर तुम जैसे जरूरत Daft है os.getcwd()औरos.path.isfile()
निक टी

15

निश्चित उत्तर: import osऔर उपयोग os.pathimport os.pathसीधे मत करो ।

मॉड्यूल के प्रलेखन से ही:

>>> import os
>>> help(os.path)
...
Instead of importing this module directly, import os and refer to
this module as os.path.  The "os.path" name is an alias for this
module on Posix systems; on other systems (e.g. Mac, Windows),
os.path provides the same operations in a manner specific to that
platform, and is an alias to another module (e.g. macpath, ntpath).
...

13
ध्यान दें कि यह एक os.pathमॉड्यूल के लिए डॉक्स नहीं है जो मौजूद नहीं है, लेकिन इसके लिए posixpath
wRAR

18
यह बिल्कुल नहीं है कि मुझे कैसे लगता है कि डॉकस्ट्रिंग की व्याख्या की जानी चाहिए, हालांकि यह बहुत भ्रामक है। ध्यान रखें कि वाक्य (या , आदि) "Instead of importing this module directly, import os and refer to this module as os.path."में स्थित है । मुझे पूरा यकीन है कि उनका मतलब यह है कि किसी को (जो काम करता है) नहीं करना चाहिए , बल्कि बेहतर पोर्टेबिलिटी के माध्यम से मॉड्यूल आयात करना चाहिए । मुझे नहीं लगता कि वे कोई सिफारिश देना चाहते हैं या नहीं । posixpath.pymacpath.pyntpath.pyimport posixpathosimport osimport os.path
59

1
मैं ज्यादातर @flornquake की टिप्पणी से सहमत हूं लेकिन अंतिम वाक्य से असहमत हूं। Posixpath.py और ntpath.py दोनों का कहना है "os आयात करें और इस मॉड्यूल को os.path के रूप में देखें"। वे यह नहीं कहते हैं कि "os.path आयात करें और इस मॉड्यूल को os.path के रूप में देखें"। macpath.py के पास मामले पर कुछ भी नहीं है।
पीट फॉर्मन

3
यह दिखाने का यह एक अच्छा उदाहरण है कि इस सूचक वाले दस्तावेज़ को कैसे गुमराह किया जा सकता है: D
Cyker

7

दिलचस्प रूप से पर्याप्त, os.path का आयात करना सभी os को आयात करेगा। इंटरएक्टिव प्रॉम्प्ट में निम्नलिखित प्रयास करें:

import os.path
dir(os)

परिणाम वैसा ही होगा, जैसे आप सिर्फ ओएस आयात करते हैं। ऐसा इसलिए है क्योंकि os.path एक अलग मॉड्यूल को संदर्भित करेगा, जिसके आधार पर आपके पास ऑपरेटिंग सिस्टम है, इसलिए पथ के लिए लोड करने के लिए किस मॉड्यूल को निर्धारित करने के लिए अजगर ऑस को आयात करेगा।

संदर्भ

कुछ मॉड्यूल के साथ, यह कहना कि यह import fooउजागर नहीं होगा foo.bar, इसलिए मुझे लगता है कि यह वास्तव में विशिष्ट मॉड्यूल के डिजाइन पर निर्भर करता है।


सामान्य तौर पर, आपके द्वारा आवश्यक सुस्पष्ट मॉड्यूलों को आयात करना थोड़ा तेज होना चाहिए। मेरी मशीन पर:

import os.path: 7.54285810068e-06 सेकंड

import os: 9.21904878972e-06 सेकंड

ये समय काफी नगण्य होने के करीब है। आपके कार्यक्रम को osअभी या बाद के समय से अन्य मॉड्यूल का उपयोग करने की आवश्यकता हो सकती है , इसलिए आमतौर पर यह सिर्फ दो माइक्रोसेकंड का त्याग करने और import osबाद में इस त्रुटि से बचने के लिए उपयोग करने के लिए समझ में आता है । मैं आमतौर पर केवल एक पूरे के रूप में ओएस का आयात करता हूं, लेकिन यह देख सकता हूं कि क्यों कुछ import os.pathतकनीकी रूप से अधिक कुशल होना पसंद करेंगे और कोड के पाठकों को बताएंगे कि यह osमॉड्यूल का एकमात्र हिस्सा है जिसे उपयोग करने की आवश्यकता होगी। यह अनिवार्य रूप से मेरे दिमाग में एक शैली के सवाल को उबालता है।


2
from os import pathअगर गति का मुद्दा है, तो कॉल को और भी तेज़ी से आगे बढ़ाएगा।
जस्टिन पील

पायथोनिक होने के नाते, स्पष्ट रूप से निहित अधिकार से बेहतर है? वास्तव में मुझे लगता है कि यह वास्तव में उपयोगकर्ता द्वारा निर्णय कॉल है, क्या उपयोगकर्ता केवल ओएस के भीतर ओएस या कई मॉड्यूल का उपयोग करने जा रहा है। हो सकता है कि एक विधि दूसरे के ऊपर आपके दर्शन के अनुरूप हो?
एंड्रयू कोउ

23
यह कुछ समय पूर्व समयपूर्व अनुकूलन मैंने कभी देखा है में से कुछ है। यह कभी किसी की अड़चन नहीं रही है और यहां का समय इस बात पर अडिग है कि किसी को कैसे कोड करना चाहिए।
माइक ग्राहम

5

सामान्य ज्ञान यहां काम करता है: osएक मॉड्यूल है, और os.pathएक मॉड्यूल भी है। तो बस उस मॉड्यूल को आयात करें जिसे आप उपयोग करना चाहते हैं:

  • यदि आप osमॉड्यूल में कार्यात्मकताओं का उपयोग करना चाहते हैं , तो आयात करें os

  • यदि आप os.pathमॉड्यूल में कार्यात्मकताओं का उपयोग करना चाहते हैं , तो आयात करें os.path

  • यदि आप दोनों मॉड्यूल में कार्यक्षमता का उपयोग करना चाहते हैं, तो दोनों मॉड्यूल आयात करें:

    import os
    import os.path

सन्दर्भ के लिए:


4

कोई निश्चित संदर्भ नहीं मिल सका, लेकिन मैं देख रहा हूं कि os.walk के लिए उदाहरण कोड os.path का उपयोग करता है, लेकिन केवल os को आयात करता है

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