2011-05-18 9 views
14

निम्न कोड उदाहरण लें:<module> आयात से ... __init__.py में मॉड्यूल का नाम दृश्यमान बनाता है?

फ़ाइल package1/__init__.py:

from moduleB import foo 
print moduleB.__name__ 

फ़ाइल package1/moduleB.py:

def foo(): pass 

फिर वर्तमान निर्देशिका से:

>>> import package1 
package1.moduleB 

यह कोड सीपीथन में काम करता है। मुझे इसके बारे में क्या आश्चर्य है कि from ... import कथन में from ... importmoduleB नाम दृश्य बनाता है। Xzx27 के अनुसार, यह मामला नहीं होना चाहिए:

फॉर्म से मॉड्यूल नाम

बाध्य नहीं करता है क्या कोई यह बता सकता है कि क्यों सीपीथन इस तरह काम करता है? क्या इसका विवरण वर्णन में कोई दस्तावेज है?

+0

क्या आप वाकई पहले 'आयात मॉड्यूलबी' नहीं हैं? – JBernardo

+0

हाँ, मुझे यकीन है। यही वह पूरी फाइल है जिस पर स्थिति को पुन: उत्पन्न किया जा सकता है। – yole

+0

मैंने कोशिश की और यह Python2.7 पर काम करता है लेकिन Python3.2 पर नहीं ... – JBernardo

उत्तर

5

प्रलेखन आप को गुमराह के रूप में यह आयात करने के लिए और अधिक आम मामले का विवरण देने में लिखा है इसमें मौजूद मूल पैकेज के बाहर से एक मॉड्यूल।

उदाहरण के लिए, अपने कोड में "उदाहरण आयात सबमिशन से" का उपयोग करके, जहां "उदाहरण" कुछ तीसरी पार्टी लाइब्रेरी पूरी तरह से अपने कोड से अनकनेक्ट है, नाम "उदाहरण" को बाध्य नहीं करता है। यह अभी भी दोनों उदाहरण/__ init__.py और उदाहरण/submodule.py मॉड्यूल आयात करता है, दो मॉड्यूल ऑब्जेक्ट्स बनाते हैं, और दूसरे मॉड्यूल ऑब्जेक्ट में example.submodule असाइन करते हैं।

लेकिन, एक सबमिशन से नामों के "से .. आयात" को मूल पैकेज ऑब्जेक्ट पर सबमिशन विशेषता सेट करनी होगी। इस पर विचार करें कि यह नहीं हुआ:

  1. पैकेज/__ init__.py पैकेज आयात होने पर निष्पादित करता है।

  2. कि __init__ "सबमिशन आयात नाम से" करता है।

  3. किसी बिंदु पर, अन्य पूरी तरह से अलग कोड "import.submodule आयात करें" करता है।

चरण 3 में, या तो sys.modules [ "package.submodule"] मौजूद नहीं है, ऐसी स्थिति में इसे फिर से लोड हो रहा है आप अलग-अलग दायरों में दो अलग मॉड्यूल वस्तुओं देगा; या sys.modules ["पैकेज।सबमिशन "] मौजूद होगा लेकिन" सबमिशन "पैरेंट पैकेज ऑब्जेक्ट (sys.modules [" package "]) की विशेषता नहीं होगी, और" import package.submodule "आयात नहीं करेगा। हालांकि, अगर यह कुछ भी नहीं करता है, तो आयात का उपयोग कोड पैकेज की विशेषता के रूप submodule उपयोग नहीं कर सकते!


सैद्धांतिक रूप से, कैसे आयात करने में एक submodule काम करता है बदला जा सकता है आयात मशीनरी के बाकी मैच के लिए बदल गया था अगर।

तुम सिर्फ जरूरत है यह जानने के लिए कि पैकेज पी से एक सबमिशन एस आयात करना क्या होगा, फिर संक्षेप में:

  1. सुनिश्चित करें कि पी आयात किया गया है, या अन्यथा आयात करें। (यह चरण "आयात A.B.C.D" को संभालने के लिए पुनरावृत्ति करता है।)
  2. मॉड्यूल ऑब्जेक्ट प्राप्त करने के लिए S.py निष्पादित करें। (.pyc फ़ाइलों, आदि के विवरण छोड़ना)
  3. sys.modules ["पीएस"] में स्टोर मॉड्यूल ऑब्जेक्ट।
  4. setattr(sys.modules["P"], "S", sys.modules["P.S"])
  5. यदि वह आयात "आयात पीएस" फ़ॉर्म का था, तो स्थानीय क्षेत्र में "पी" बांधें।
+0

संशोधन के बाद पाइथन खोल को पुनरारंभ करना भूल जाता हूं और पैकेज के \ _ \ _ init__.py के अंदर अयोग्य नामों को हल करने का दायरा पैकेज ऑब्जेक्ट के गुणों में शामिल है, है ना? – yole

+0

@yole: हाँ, globals() \ _ \ _ init \ _ \ _ में पाई sys.modules ["पैकेज"] है। \ _ \ _ Dict \ _ \ _। –

0

ऐसा इसलिए है क्योंकि __init__.py रनटाइम पर पैकेज 1 मॉड्यूल ऑब्जेक्ट के रूप में स्वयं को प्रस्तुत करता है, इसलिए प्रत्येक .py फ़ाइल को एक सबमिशन के रूप में परिभाषित किया जाएगा। और __all__ को फिर से लिखना कोई समझ नहीं पाएगा। आप एक और फ़ाइल बना सकते हैं जैसे example.py और इसे __init__.py में उसी कोड से भरें और यह NameError बढ़ाएगा।

मुझे लगता है कि CPython क्रम विशेष एल्गोरिथ्म लेता है जब __init__.py चर की तलाश में अन्य अजगर फ़ाइलों से अलग, इस तरह हो सकता है:

looking for variable named "moduleB" 
if not found: 
    if __file__ == '__init__.py': #dont raise NameError, looking for file named moduleB.py 
     if current dir contains file named "moduleB.py": 
         import moduleB 
     else: 
        raise namerror 
+1

के समान प्रभाव प्राप्त करने के लिए '। मॉड्यूल बी आयात foo' से 'का उपयोग करें। यह उतना आसान नहीं है। यदि आप मॉड्यूलबी को \ _ \ _ init__.py में आयात नहीं करते हैं, तो नाम हल नहीं किया जाएगा। – yole

+0

@ योल हां, क्षमा करें। मैं – MBarsi

संबंधित मुद्दे