2013-06-21 7 views
6

मैं सजावट के बारे में यह article पढ़ रहा हूं।नेस्टेड फ़ंक्शंस में पायथन वैरिएबल स्कोप

चरण 8 पर, वहाँ एक समारोह के रूप में परिभाषित किया गया है:

def outer(): 
    x = 1 
    def inner(): 
     print x # 1 
    return inner 

और यदि हम इसे द्वारा चलाए: यह एक्स प्रिंट नहीं करता

>>> foo = outer() 
>>> foo.func_closure # doctest: +ELLIPSIS 

। स्पष्टीकरण के अनुसार:

सब कुछ पाइथन के स्कॉइंग नियमों के अनुसार काम करता है - एक्स एक स्थानीय हमारे कार्य बाहरी में चर है। जब आंतरिक प्रिंट्स x # बिंदु पर पाइथन स्थानीय चर के लिए आंतरिक रूप से दिखता है और यह नहीं ढूंढता है तो यह को उस क्षेत्र को संलग्न करता है जो कार्य बाहरी है, इसे वहां ढूंढ रहा है।

लेकिन परिवर्तनीय जीवनकाल के दृष्टिकोण से चीजों के बारे में क्या? हमारे परिवर्तनीय x फ़ंक्शन बाहरी के लिए स्थानीय है जिसका अर्थ है कि यह केवल मौजूद है जबकि फ़ंक्शन बाहरी चल रहा है। हम बाहरी की वापसी के बाद तक आंतरिक कॉल करने में सक्षम नहीं हैं, इसलिए हमारे मॉडल के मुताबिक पाइथन काम करता है, जब तक हम आंतरिक रूप से कॉल नहीं करते हैं और शायद किसी प्रकार की रनटाइम त्रुटि होनी चाहिए, तब तक एक्स मौजूद नहीं होना चाहिए।

हालांकि, मैं वास्तव में समझ नहीं पा रहा हूं कि दूसरा अनुच्छेद क्या है।

मैं समझता हूं कि आंतरिक() को एक्स का मान मिलता है लेकिन यह एक्स को क्यों प्रिंट नहीं करता है?

धन्यवाद

अद्यतन:

सभी प्रश्नों के उत्तर के लिए धन्यवाद। अब मैं कारण समझता हूं। यही वजह है कि आंतरिक() एक्स के रूप में यह सभी

उत्तर

2

में नहीं बुलाया जाता है मुद्रित नहीं है "लौट भीतरी" सिर्फ एक सूचक भीतरी() करने के लिए है, लेकिन यह निष्पादित नहीं होता है, आप inner पर कॉल नहीं कर रहे हैं। आपने outer कहा है, जो inner देता है, लेकिन इसे कॉल किए बिना। यदि आप inner पर कॉल करना चाहते हैं, तो foo() करें (क्योंकि आपने outer() के परिणाम foo पर परिणाम का आकलन किया है)।

आपके द्वारा उद्धृत पैराग्राफ इस मुद्दे के लिए टेंगेंशियल है। आप कहते हैं कि आप पहले ही समझ चुके हैं कि क्यों innerx का मान प्राप्त करता है, जो पैराग्राफ समझा रहा है। असल में, यदि एक स्थानीय चर का उपयोग नेस्टेड फ़ंक्शन में किया जाता है, और उस नेस्टेड फ़ंक्शन को वापस कर दिया जाता है, तो चर के मान को लौटाए गए फ़ंक्शन के साथ संग्रहीत किया जाता है, भले ही उस चर को जहां सक्रिय किया गया हो, अब सक्रिय नहीं है। आम तौर पर xouter के बाद समाप्त हो जाएगा, क्योंकि xouter पर स्थानीय है। लेकिन outerinner लौटाता है, जिसे अभी भी x तक पहुंच की आवश्यकता है।तो x को बंद करने के रूप में लपेटा जाता है, इसलिए इसे बाद में inner तक पहुंचा जा सकता है।

+0

ओपी भी पूछ रहा है क्यों 'x' अभी भी – jamylak

+0

@jamylak मौजूद है: यह है कि क्या वह है या नहीं है मेरे लिए स्पष्ट नहीं है। वह कहता है कि वह उद्धृत अनुच्छेद को समझ में नहीं आता है, लेकिन यह भी कहता है कि वह समझता है कि 'आंतरिक' को 'x' तक कैसे पहुंच है। – BrenBarn

+0

किसी भी तरह से आपने इसे अभी स्पष्ट कर दिया है ''nonlocal'' कथन के लिए – jamylak

7

मैं समझता हूं कि आंतरिक() को एक्स का मान मिलता है लेकिन यह एक्स आउट क्यों नहीं प्रिंट करता है?

यह कुछ भी प्रिंट नहीं करता है क्योंकि आपने अभी तक आंतरिक फ़ंक्शन नहीं कहा है।

>>> def outer(): 
     x = 1 
     def inner(): 
       print x # 1 
     return inner 
...  
>>> func = outer() 
>>> func    
<function inner at 0xb61e280c> 
>>> func() 
1 

यह (x की यानी मूल्य)

एक closure कहा जाता है, यानी भले ही बाहरी समारोह अब और ढेर (समाप्त क्रियान्वित) में नहीं है, लेकिन अभी भी आंतरिक समारोह है कि यह वापस नहीं लौटाई गई याद है यह राज्य है।

459 if len(code.co_freevars) == 0: 
    460  closure = NULL 
    461 else: 
    462  len(closure) == len(code.co_freevars) 

py3.x में आप कर सकते हैं अल:

>>> def outer(): 
      x = 1 
      y = 2 
      def inner(): 
        z=3 
        print x 
      return inner 
...  
>>> func = outer() 
>>> func.func_code.co_freevars #returns the variables that were used in closure 
('x',) 

कैसे अजगर यह निर्णय लेता है पर source code से बंद करने या नहीं है इसलिए के मूल्य को nonlocal कथन के अंदर आंतरिक फ़ंक्शन के अंदर संशोधित करें।

>>> def outer(): 
     x = 1 
     def inner(): 
      nonlocal x 
      x += 1 
      print (x) 
     return inner 
...  
>>> func = outer() 
>>> func() 
2 
>>> func() 
3 
>>> func() 
4 
+2

+1 – Tregoreg

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