2011-08-19 15 views
9

अगर मैं एक मॉड्यूल आयात करते हैं, मॉड्यूल का नाम ऊपर sys.modules और globals() दोनों में पता चलता है। अगर मैं इसे फिर से हटा देता हूं, तो इसे globals() से हटा दिया जाता है, लेकिन फिर भी sys.modules में रहता है। ऐसा क्यों है?मॉड्यूल का नाम()

import mymodule 
'mymodule' in globals() # True 
'mymodule' in sys.modules # True 
del mymodule 
'mymodule' in globals() # False 
'mymodule' in sys.modules # Still True, why? 

मैं भी निम्न अंतर नहीं पाया:

from mypackage import mymodule 
'mypackage' in sys.modules   # True 
'mymodule' in sys.modules   # False ! 
'mypackage.mymodule' in sys.modules # also True ! 

जबकि जवाब globals() के लिए पूरक हैं:

'mypackage' in sys.modules   # False 
'mymodule' in sys.modules   # True 
'mypackage.mymodule' in sys.modules # False 
+0

यह * sys.modules, 'del sys.modules [' mymodule ']' से मॉड्यूल को निकालना संभव है, और यह कभी-कभी उपयोगी होता है। – SingleNegationElimination

उत्तर

4

बस किसी भी अन्य अजगर वस्तु की तरह, एक मॉड्यूल का अस्तित्व तक वहां इसे करने के लिए कोई और अधिक संदर्भ हैं जारी है। दूसरे शब्दों में, sys.modules एक नियमित dict की तरह बर्ताव करता है, और

import mymodule 
lst = {mymodule.__name__: mymodule} 
'mymodule' in globals() # True 
'mymodule' in lst   # True 
del mymodule 
'mymodule' in globals() # False 
'mymodule' in lst   # Still True 

sys.modules केवल आयात बयानों पर विचार-विमर्श कर रहा है। पाइथन इसे अगली बार आयात होने पर रीलोड करने के लिए आप sys.modules से मॉड्यूल हटा सकते हैं।

3

क्योंकि अजगर sys.modules में मॉड्यूल कैश को रोकने के लिए (महंगा, धीमी गति से) मॉड्यूल-खोज प्रक्रिया आवश्यक से अधिक चल रही है।

यह sys.modules से मॉड्यूल को निकालने के लिए ठीक है अगर आप की जरूरत है, हालांकि reload भी काम कर सकते हैं।


अधिक जानकारी में, जब आप import mymodule विभिन्न चीजें होती हैं। मेरे सिर के ऊपर है, और यह सोचते हैं mymodule दुभाषिया निष्पादन करने के लिए बनाया मॉड्यूल से एक नहीं है बंद:

  1. दुभाषिया mymodule युक्त फ़ाइल का पता लगा कुछ जटिल कोड चलाता है (यह हो सकता है mymodule.py, mymodule.pyc , या mymodule.pyd - या शायद कुछ और जिसे मैंने नहीं सोचा है। यह वर्तमान निर्देशिका, sys.path, और अन्य स्थानों के माध्यम से भी दिखता है।

  2. इस प्रकार स्थित फ़ाइल लेक्स, पार्स और संकलित है (आवश्यक हो तो) दुभाषिया bytecodes में यदि।

  3. संकलित मॉड्यूल निष्पादित किया जाता है, जो मॉड्यूल ऑब्जेक्ट देता है।

  4. मॉड्यूल वस्तु sys.modules में डाला जाता है।

  5. मॉड्यूल वस्तु स्थानीय import बयान में निर्दिष्ट चर के लिए बाध्य है।

, तो, (ऊपर एक अनुमान है कि मैं क्या import पीछे यांत्रिकी के बारे में याद पर आधारित है। यह शायद महत्वपूर्ण और सूक्ष्म तरीकों से गलत है।)

ध्यान दें कि करने के लिए मॉड्यूल वस्तु बंधन स्थानीय नाम वास्तव में वास्तविक आयात प्रक्रिया का एक छोटा सा हिस्सा है। del mymodule निष्पादित करके बाध्यकारी नाम को हटाकर, शेष आयात को प्रभावित नहीं करता है।

+1

लेकिन अगर मैं 'del mymodule' निष्पादित करके बाध्यकारी नाम हटा देता हूं, तो मैं इसे नामस्थान से हटा देता हूं ताकि मैं 'आयात mymodule' निष्पादित कर सकूं और इन दोनों चरणों को एक साथ 'रीलोड (mymodule)' निष्पादित करने के बराबर है, है ना? – HongboZhu

+1

@ हांगबो: गलत: 'आयात' पहले 'sys.modules' में दिखता है यह देखने के लिए कि क्या यह पहले ही मॉड्यूल आयात कर चुका है या नहीं। यदि यह है, तो यह आपको मॉड्यूल ऑब्जेक्ट देगा जो इसे मॉड्यूल आयात करते समय बनाया गया था। चूंकि 'del mymodule' मॉड्यूल ऑब्जेक्ट को 'sys.modules' से नहीं हटाता है, फिर से इसे आयात करने से' sys.modules' में ऑब्जेक्ट में नाम को पुनर्निर्मित किया जाएगा। – katrielalex

+1

@ हांगबो: यदि आप मॉड्यूल को फिर से आयात करना चाहते हैं, तो 'पुनः लोड करें (मॉड्यूल)' करें। इसके बराबर, इसे 'sys.modules' से हटाएं और फिर' आयात करें '। – katrielalex

4

del उचित दायरे में किसी नाम के बाध्यकारी को हटा देता है; इसमें प्रति मॉड्यूल के साथ कुछ लेना देना नहीं है।

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

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