2010-05-13 5 views
156

मैं पाइथन के लिए नया हूं, इसलिए यह शायद एक साधारण स्कॉइंग प्रश्न है। एक अजगर फ़ाइल (मॉड्यूल) में निम्न कोड मुझे थोड़ा भ्रमित है:यदि किसी कथन में प्रारंभ किए गए चर का दायरा क्या है?

if __name__ == '__main__': 
    x = 1 

print x 

अन्य भाषाओं मैं में काम किया है में, इस कोड एक अपवाद फेंक, x चर के रूप में if बयान करने के लिए स्थानीय है और होना चाहिए इसके बाहर मौजूद नहीं है। लेकिन यह कोड निष्पादित करता है, और प्रिंट करता है 1. क्या कोई इस व्यवहार को समझा सकता है? क्या मॉड्यूल ग्लोबल/पूरे मॉड्यूल में उपलब्ध सभी चर?

+7

एक और प्रश्नोत्तरी आपको इस बारे में पता नहीं हो सकता है: यदि उपरोक्त 'if' कथन सत्य नहीं है (यानी, '__name__' * नहीं'' __main __ 'है, उदाहरण के लिए जब आप इसे निष्पादित करने के बजाय मॉड्यूल आयात करते हैं शीर्ष-स्तर), फिर 'x' कभी बाध्य नहीं होगा, और बाद में' प्रिंट x' कथन 'नाम' फेंक देगा: नाम 'x' परिभाषित नहीं किया गया है '। – Santa

उत्तर

155

पायथन चर को आंतरिक कार्य, कक्षा या मॉड्यूल में रखा गया है जिसमें उन्हें असाइन किया गया है। if और while ब्लॉक जैसे नियंत्रण ब्लॉक गिनते नहीं हैं, इसलिए if के अंदर आवंटित एक चर अभी भी फ़ंक्शन, क्लास या मॉड्यूल पर स्कॉप्ड है।

(अंतर्निहित एक जनरेटर अभिव्यक्ति या सूची/सेट/dict समझ द्वारा परिभाषित किया गया काम करता है, गिनती कर के रूप में लैम्ब्डा भाव से करते हैं। आप उन में से किसी में एक काम बयान सामान नहीं कर सकते, लेकिन लैम्ब्डा मापदंडों और for खंड लक्ष्य कर रहे हैं निहित असाइनमेंट।)

36

हाँ, वे एक ही "स्थानीय गुंजाइश" में हैं, और वास्तव में इस तरह कोड पायथन में आम है:

if condition: 
    x = 'something' 
else: 
    x = 'something else' 

use(x) 

ध्यान दें कि x घोषित या जैसे कि यह होगा, हालत से पहले आरंभ नहीं किया है उदाहरण के लिए सी या जावा में रहें।

दूसरे शब्दों में, पायथन में ब्लॉक-स्तरीय स्कोप नहीं हैं। सावधान रहो, हालांकि, जो स्पष्ट रूप से एक NameError अपवाद उठाएंगे ऐसे

if False: 
    x = 3 
print(x) 

के रूप में उदाहरण के साथ।

1

हां। यह for दायरे के लिए भी सच है। लेकिन पाठ्यक्रम के काम नहीं।

आपके उदाहरण में: यदि if कथन में स्थिति गलत है, x हालांकि परिभाषित नहीं किया जाएगा।

1

आप इस कोड को कमांड लाइन से निष्पादित कर रहे हैं इसलिए if स्थितियां सत्य हैं और x सेट है। की तुलना करें:

>>> if False: 
    y = 42 


>>> y 
Traceback (most recent call last): 
    File "<pyshell#6>", line 1, in <module> 
    y 
NameError: name 'y' is not defined 
28

अजगर में स्कोप इस क्रम इस प्रकार है:

  • स्थानीय गुंजाइश

  • खोजें किसी भी संलग्न कार्यों के दायरे खोजें

  • वैश्विक क्षेत्र खोजें

  • अंतर्निर्मित खोजें

(source)

सूचना है कि if और अन्य पाशन/शाखाओं में निर्माणों सूचीबद्ध हैं नहीं - केवल कक्षाएं, काम करता है, और मॉड्यूल अजगर में गुंजाइश प्रदान करते हैं, तो कुछ भी एक if ब्लॉक में घोषित किया गया है एक ही गुंजाइश जैसा कि कुछ भी ब्लॉक के बाहर decleared। चर संकलन समय पर चर की जांच नहीं की जाती है, यही कारण है कि अन्य भाषाएं अपवाद फेंकती हैं। पायथन में, जब तक आपको इसकी आवश्यकता होती है वैरिएबल मौजूद होता है, तब तक कोई अपवाद नहीं फेंक दिया जाएगा।

5

जैसा कि एली ने कहा, पायथन को परिवर्तनीय घोषणा की आवश्यकता नहीं है।सी में आप कह सकते हैं कि:

int x; 
if(something) 
    x = 1; 
else 
    x = 2; 

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

एकमात्र कारण यह है कि एक स्थिर रूप से टाइप की गई भाषा इस समस्या के कारण if कथन के बाहर चर घोषित करने के लिए सीमित है। गतिशील गले लगाओ!

7

सी जैसी भाषाओं के विपरीत, एक पायथन वैरिएबल पूरे कार्य (या कक्षा, या मॉड्यूल) के दायरे में है जहां यह दिखाई देता है, न कि केवल "ब्लॉक" में। ऐसा लगता है कि आपने फ़ंक्शन (या कक्षा, या मॉड्यूल) के शीर्ष पर int x घोषित किया है, सिवाय इसके कि पाइथन में आपको चर घोषित करने की आवश्यकता नहीं है।

ध्यान दें कि परिवर्तनीय x का अस्तित्व केवल रनटाइम पर चेक किया जाता है - यानी, जब आप print x कथन प्राप्त करते हैं। यदि __name__"__main__" के बराबर नहीं था तो आपको एक अपवाद मिलेगा: NameError: name 'x' is not defined

+0

कक्षाएं कोई दायरा नहीं बनाती हैं; एक वर्ग में एक "स्थानीय" चर केवल सृजन पर कक्षा के निर्देश में जोड़ा जाता है। – chepner

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