2012-10-11 30 views
9

में "आयात lib.foo" और "lib के रूप में lib.foo आयात करें" के बीच अंतर पाइथन में परिपत्र आयात को कैसे प्रबंधित किया जाता है, इस बारे में मुझे परेशान है। मैंने एक न्यूनतम प्रश्न को दूर करने की कोशिश की है और मुझे नहीं लगता कि यह सटीक संस्करण पहले पूछा गया था। असल में, मैं जब मैं lib.foo और lib.bar के बीच एक सर्कुलर निर्भरता हैपायथन

और

के बीच

import lib.foo 
import lib.foo as f 
एक फर्क दिखाई दे रही है। मैंने उम्मीद की थी कि दोनों एक ही काम करेंगे: (संभवतः आधा प्रारंभिक) मॉड्यूल sys.modules में पाया जाएगा और स्थानीय नामस्थान में रखा जाएगा। (परीक्षण से मैंने देखा है कि वास्तव में import lib.foo स्थानीय नेम स्पेस में lib डालता है -। ठीक है, कि वाक्य रचना मैं lib.foo.something वैसे भी करूँगा के साथ),

लेकिन अगर lib.foosys.modules में पहले से ही है, तो import lib.foo as f विशेषता के रूप में foo का उपयोग करने की कोशिश करता है lib पर और विशेषता Error बढ़ाता है। व्यवहार (प्रतीत होता है) sys.modules में मौजूदगी पर निर्भर क्यों करता है?

इसके अलावा, यह व्यवहार कहां दस्तावेज किया गया है? मुझे नहीं लगता कि Python import statement reference इस व्यवहार को बताता है, या कम से कम मैं इसे निकाला नहीं जा सका :-)

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

from project.package import moduleA 
from project.package import moduleB 

लेकिन यह दो मॉड्यूल के बीच परिपत्र आयात होने पर विफल रहता है। मैंने उम्मीद की थी कि जब तक दो मॉड्यूल में शीर्ष-स्तरीय परिभाषाएं एक दूसरे पर निर्भर न हों (उदा। moduleA में बेस क्लास के साथ moduleB में कोई सबक्लास नहीं है)।

टेस्ट स्क्रिप्ट:

#!/bin/sh 
rm -r lib; mkdir lib 

touch lib/__init__.py 

cat > lib/foo.py <<EOF 
# lib.foo module 
print '{ foo' 
#import lib.bar # works 
import lib.bar as b # also works 
#from lib import bar # also works 
print 'foo }' 
EOF 

cat > lib/bar.py <<EOF 
# lib.bar module 
print '{ bar' 
#import lib.foo # works 
import lib.foo as f # AttributeError: 'module' object has no attribute 'foo' 
#from lib import foo # ImportError: cannot import name foo 
print 'bar }' 
EOF 

python -c 'import lib.foo' 
+0

लिंक http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Imports#Imports टूटा हुआ है - –

उत्तर

6

जब आप कहते हैं कि import lib.foo as f क्या आप अजगर करने के लिए कह रहे हैं बाईटकोड स्तर पर import lib.foo; f = lib.foo के बराबर है। इस मुद्दे में आप एक विशेषता एरर के साथ समाप्त हो गए हैं क्योंकि lib इस मामले में foo अभी तक एक विशेषता के रूप में सेट नहीं है। पाइथन ने lib.foo का आयात पूरा नहीं किया है जब यह असाइनमेंट करने का प्रयास करता है और इस प्रकार lib पर अभी तक विशेषता सेट नहीं की गई है; आयात के लिए पायथन 3.3 स्रोत देखें जहां आप देख सकते हैं कि module is loaded बनाम जोड़े कथन कहां से नीचे module is set on its parent है।

यह वह जगह है जहां आप कुछ परिपत्र आयात मुद्दों के साथ समाप्त होते हैं। lib.foo तक पहुंचने का प्रयास करने से पहले आपको lib.foo के लिए आयात करने की आवश्यकता है, अन्यथा lib पर विशेषता बस बाइटकोड तक पहुंचने के लिए मौजूद नहीं होगी। ऐसा इसलिए हो सकता है कि आप सोचते हैं कि आप सीधे अपने कोड में किसी शीर्ष-स्तरीय परिभाषा का उपयोग नहीं कर रहे हैं, लेकिन वास्तविकता में आप अपने आयात विवरणों के माध्यम से हैं।

+0

पढ़ने के लिए अच्छा होगा जवाब के लिए धन्यवाद! इसलिए जब मैं 'lib.foo' आयात करता हूं, तो 'lib' पहले आयात किया जाता है और जब' lib.foo' आयात किया जाता है, तो 'lib' विशेषता 'lib' में सेट की जाती है। यही कारण है कि 'lib.foo.something' बाद में काम करता है: इसे 'lib' पैकेज पर' foo' * विशेषता * मिलती है - यह भी बताती है कि क्यों' lib.foo 'आयात स्थानीय नामस्थान में 'lib' डालता है। –

+0

हाँ, यह सब सही है। –