2015-06-04 8 views
6

मैं एक समस्या को समझ कर कोड के निम्न भाग के परिणाम के साथ हो रहा है है बनाम:अजगर वर्ग और वैश्विक स्थानीय चर

my_str = "outside func" 
def func(): 
    my_str = "inside func" 
    class C(): 
     print(my_str) 
     print((lambda:my_str)()) 
     my_str = "inside C" 
     print(my_str) 

उत्पादन होता है:

outside func 
inside func 
inside C 

कोड का एक और टुकड़ा है:

my_str = "not in class" 
class C: 
    my_str = "in the class" 
    print([my_str for i in (1,2)]) 
    print(list(my_str for i in (1,2))) 

उत्पादन होता है:

[‘in the class’, 'in the class’] 
['not in class’, 'not in class’] 

सवाल यह है:

  1. क्या प्रत्येक प्रिंट() बयान में यहां हो रहा है?
  2. क्या कोई क्यों समझा सकता है प्रिंट() कथन विभिन्न नामस्थानों से स्ट्रिंग प्राप्त करता है?

संपादित करें 1:

मुझे लगता है कि इस this question से अलग है क्योंकि मैं विनम्रतापूर्वक वहाँ जवाब लगता है इस बदलाव की व्याख्या नहीं करते:

my_str = "outside func" 
def func(): 
    my_str = "inside func" 
    class C(): 
     print(my_str) 
     print((lambda:my_str)()) 
     #my_str = "inside C" 
     print(my_str) 

उत्पादन होता है:

inside func 
inside func 
inside func 

संपादित करें 2:

दरअसल, इस this question से डुप्लिकेट है क्योंकि मार्टिन पीटर्स कहते हैं:

जवाब में कहा गया है: एक नाम लगभग शुरू में एक वर्ग के शरीर, भीतर करने के लिए सौंपा गया है। आपने my_str को असाइन किया है, इसे उसी मामले में बना रहा है। उस लाइन पर टिप्पणी करने का मतलब है कि अब आप my12str पर असाइन नहीं कर रहे हैं, इसे एक्स के समान केस बनाते हैं।


+0

@MartijnPieters अंटी के खूबसूरत उत्तर में पहला मामला शामिल है। दूसरा मामला उस पर उलझ जाता है लेकिन फिर भी यह एक सटीक डुप्ली नहीं है। शायद मैं इस प्रश्न पर भविष्य के आगंतुकों के लिए उस लिंक को छोड़ दूंगा। (आप पहले से ही मसौदा संस्कार तैयार कर चुके हैं;)) –

+2

@ भार्गवराव: क्षमा करें, मुझे वास्तव में माना जाता है कि आप [पायथन स्कॉइंग नियमों का संक्षिप्त वर्णन] (http://stackoverflow.com/q/291978) से लिंक कर रहे थे! यह वास्तव में एक डुप्ली है। –

उत्तर

5

यहाँ चार स्कोप हैं:

  1. वैश्विक क्षेत्र
  2. समारोह गुंजाइश
  3. वर्ग शरीर
  4. लैम्ब्डा गुंजाइश

जब बनाने ए वर्ग विवरण, वर्ग निकाय को एक समारोह के रूप में निष्पादित किया जाता है और उस 'फ़ंक्शन' का स्थानीय नामस्थान वर्ग गुणों के रूप में उपयोग किया जाता है।

हालांकि, एक वर्ग निकाय एक गुंजाइश नहीं है, और जैसे कार्यों से अलग व्यवहार करता है। एक समारोह निकाय में, बाध्यकारी दायरे को परिभाषित करता है; किसी फ़ंक्शन में किसी नाम को असाइन करें और इसे स्थानीय के रूप में चिह्नित किया गया है।एक वर्ग में, किसी नाम को असाइन करने से यह वैश्विक बनाता है जब तक आप वास्तव में असाइनमेंट नहीं करते।

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

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

आखिरकार, आप क्लास बॉडी में स्थानीय नाम my_str को असाइन करते हैं, और उस स्थानीय को प्रिंट करते हैं।

जिस क्षण आप असाइनमेंट को हटाते हैं, कक्षा में नाम गैर-स्थानीय माना जाता है; पहले और अंतिम print() कथन अब बराबर हैं, और नाम सामान्य स्कॉइंग नियमों के अनुसार बस देखा जाता है।

+0

क्या आप संपादन 1 की विविधता को समझाने के लिए अपना उत्तर बढ़ा सकते हैं? – Dargor

+3

@PabloGalindoSalgado: केवल आपका संपादन * पुष्टि करता है कि पोस्ट एक डुप्ली है। –

+0

मुझे बहुत खेद है, तो। मैंने दो बार जवाब पढ़े और उस बदलाव को समझ में नहीं आया .... लेकिन जैसा आपने कहा था उतना सीधा है। कॉफी के लिए समय :( – Dargor

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