2010-06-21 28 views
13

मैं एक पाइथन नौसिखिया सी ++ पृष्ठभूमि से आ रहा हूं। जबकि मुझे पता है कि यह मेरे पुराने सी ++ ज्ञान का उपयोग करके एक मिलान करने वाली अवधारणा को खोजने का प्रयास करने के लिए पाइथोनिक नहीं है, मुझे लगता है कि यह प्रश्न अभी भी पूछने के लिए एक सामान्य प्रश्न है:पायथन मॉड्यूल प्रारंभिक आदेश?

सी ++ के तहत, वैश्विक/स्थिर चर प्रारंभिक नामक एक प्रसिद्ध समस्या है ऑर्डर फियास्को, सी ++ की अक्षमता के कारण यह तय करने के लिए कि कौन सा ग्लोबल/स्टेटिक वैरिएबल पहले संकलन इकाइयों में शुरू किया जाएगा, इस प्रकार विभिन्न संकलन इकाइयों में किसी एक के आधार पर एक वैश्विक/स्थैतिक चर इसके निर्भरता समकक्षों की तुलना में पहले शुरू किया जा सकता है, और जब निर्भर निर्भरता वस्तु द्वारा प्रदान की जाने वाली सेवाओं का उपयोग करें, हमारे पास अपरिभाषित व्यवहार होगा। यहां मैं इस समस्या को हल करने के तरीके पर बहुत गहराई से नहीं जाना चाहता हूं। :)

पायथन दुनिया पर, मुझे वैश्विक चर के उपयोगों को भी देखा जाता है, यहां तक ​​कि अलग-अलग .py फ़ाइलों में भी, और एक टाइपटाइक उपयोग केस मैंने देखा था: एक वैश्विक वस्तु को एक .py फ़ाइल में प्रारंभ करें, और अन्य .py फाइलें, कोड केवल निडरता से वैश्विक वस्तु का उपयोग करना शुरू कर देता है, यह मानते हुए कि इसे कहीं और शुरू किया जाना चाहिए, जो ऊपर उल्लिखित समस्या के कारण सी ++ के तहत निश्चित रूप से अस्वीकार्य है।

मुझे यकीन नहीं है कि उपर्युक्त उपयोग केस पायथन (पायथनिक) में सामान्य अभ्यास है, और पाइथन सामान्य रूप से इस प्रकार की वैश्विक चर प्रारंभिकरण समस्या को कैसे हल करता है?

बहुत बहुत धन्यवाद!

लिन

उत्तर

10

सी ++ के तहत, वैश्विक/स्थिर चर प्रारंभ आदेश च नामक एक अच्छी तरह से ज्ञात समस्या है iasco, सी ++ के तय करने में असमर्थता जो वैश्विक/स्थिर चर संकलन इकाइयों में पहले प्रारंभ किया जाएगा के कारण,

मुझे लगता है कि बयान ++ पायथन और सी के बीच एक महत्वपूर्ण अंतर पर प्रकाश डाला गया: अजगर में, ऐसी कोई बात के रूप में अलग है संकलन इकाइयों। इसका मतलब है कि, सी ++ (जैसा कि आप जानते हैं) में, दो अलग-अलग स्रोत फ़ाइलों को एक-दूसरे से पूरी तरह से स्वतंत्र रूप से संकलित किया जा सकता है, और इस प्रकार यदि आप फ़ाइल ए में एक रेखा की तुलना करते हैं और फ़ाइल बी में एक पंक्ति की तुलना करते हैं, तो कुछ भी नहीं कहना है आप जो कार्यक्रम में पहले रखा जाएगा। यह कई धागे के साथ स्थिति की तरह है: आप यह नहीं कह सकते कि थ्रेड 1 में कोई विशेष कथन थ्रेड 2 में किसी विशेष कथन से पहले या उसके बाद निष्पादित किया जाएगा या नहीं। आप कह सकते हैं कि सी ++ प्रोग्राम समानांतर में संकलित किए गए हैं।

इसके विपरीत, पायथन में, निष्पादन एक फ़ाइल के शीर्ष पर शुरू होता है और फ़ाइल में प्रत्येक कथन के माध्यम से एक अच्छी तरह से परिभाषित क्रम में आगे बढ़ता है, जहां वे आयात किए जाते हैं उन बिंदुओं पर अन्य फ़ाइलों को ब्रांच करते हैं।वास्तव में, आप लगभग import निर्देश #include के रूप में सोच सकते हैं, और इस तरह आप प्रोग्राम में सभी स्रोत फ़ाइलों में कोड की सभी पंक्तियों के निष्पादन के आदेश की पहचान कर सकते हैं। (ठीक है, यह उससे थोड़ा अधिक जटिल है, क्योंकि मॉड्यूल केवल आयात किए जाने पर पहली बार निष्पादित हो जाता है, और अन्य कारणों से।) यदि सी ++ प्रोग्राम समानांतर में संकलित किए जाते हैं, तो पाइथन प्रोग्राम को क्रमशः व्याख्या किया जाता है।

आपका प्रश्न पायथन में मॉड्यूल के गहन अर्थ पर भी छूता है। एक पायथन मॉड्यूल - जो कुछ भी है जो एक .py फ़ाइल में है - एक वास्तविक वस्तु है। एक स्रोत स्रोत में "वैश्विक" दायरे में घोषित सब कुछ वास्तव में उस मॉड्यूल ऑब्जेक्ट की विशेषता है। पायथन में कोई वास्तविक वैश्विक दायरा नहीं है। (पायथन प्रोग्रामर अक्सर "वैश्विक" कहते हैं और वास्तव में भाषा में global कीवर्ड है, लेकिन यह हमेशा वर्तमान मॉड्यूल के शीर्ष स्तर को संदर्भित करता है।) मैं देख सकता था कि उपयोग करने के लिए एक अजीब अवधारणा है एक सी ++ पृष्ठभूमि से आ रहा है। जावा से आने वाले कुछ लोगों ने मेरे लिए उपयोग किया, और इस संबंध में जावा सी ++ की तुलना में पाइथन के समान ही है।

मुझे लगता है कि अजगर में यह किसी भी विचार है कि क्या यह शुरू कर दिया गया/परिभाषित या नहीं बिना एक चर का उपयोग करने के लिए पूरी तरह से सामान्य है उल्लेख होगा (वहाँ भी जावा में कोई वैश्विक गुंजाइश है)। खैर, शायद सामान्य नहीं, लेकिन कम से कम उचित परिस्थितियों में स्वीकार्य है। पायथन में, एक अपरिभाषित चर का उपयोग करने की कोशिश कर रहा है NameError; आप सी या सी ++ में मनमाने ढंग से व्यवहार नहीं कर सकते हैं, ताकि आप आसानी से स्थिति को संभाल सकें।

try: 
    duck.quack() 
except NameError: 
    pass 

जो अगर duck मौजूद नहीं है कुछ नहीं करता है: आप इस पैटर्न देख सकते हैं। वास्तव में, क्या आप और अधिक सामान्यतः देखेंगे

try: 
    duck.quack() 
except AttributeError: 
    pass 

अगर duck एक विधि quack नामित नहीं है जो कुछ नहीं करता है। (AttributeError किसी ऑब्जेक्ट की विशेषता तक पहुंचने का प्रयास करते समय आपको मिली त्रुटि होती है, लेकिन ऑब्जेक्ट में उस नाम से कोई विशेषता नहीं होती है।) यह पाइथन में एक प्रकार की जांच के लिए गुजरता है: हम समझते हैं कि अगर हम सभी बतख करने के लिए बतख की ज़रूरत है, हम इसे क्वैक करने के लिए कह सकते हैं, और यदि ऐसा होता है, तो हमें परवाह नहीं है कि यह वास्तव में एक बतख है या नहीं। (यह बतख टाइपिंग ;-) कहा जाता है

+0

यह निश्चित रूप से मेरे द्वारा पोस्ट किए गए मुद्दे की पूरी तरह से व्याख्या है, बिल्कुल बिंदु पर! धन्यवाद! – Lin

12

अजगर आयात शुरू से अंत तक से नए अजगर मॉड्यूल निष्पादित करता है। बाद के आयात केवल sys.modules में मौजूदा संदर्भ की एक प्रति में परिणामस्वरूप होते हैं, भले ही सर्कुलर आयात के कारण मॉड्यूल आयात करने के बीच में भी। मॉड्यूल विशेषताएँ ("वैश्विक चर" वास्तव में मॉड्यूल स्कोप पर हैं) जिन्हें सर्कुलर आयात मौजूद होने से पहले शुरू किया गया है।

main.py:

import a 

a.py:

var1 = 'foo' 
import b 
var2 = 'bar' 

b.py:

import a 
print a.var1 # works 
print a.var2 # fails 
+0

तो अजगर वैश्विक चर प्रारंभ आदेश किया जाता है और "आयात" बयान है, जो समझ में आता है, के बाद से सी ++ कोई रास्ता नहीं स्पष्ट रूप से संकलन इकाई निर्भरता रिश्तों निर्दिष्ट करने के लिए है के माध्यम से स्पष्ट रूप से लागू की जाती है। इसे स्पष्ट करने के लिए धन्यवाद! – Lin

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