2014-10-04 6 views
8

कार्यों के विपरीत, एक वर्ग 'शरीर परिभाषा समय में क्रियान्वित किया जाता है:परिभाषा समय पर कक्षा के शरीर को क्यों निष्पादित किया जाता है?

class A(object): 
    print 'hello' 

आउट:

hello 

यह मामला क्यों है? क्या यह @classmethod/@staticmethod विधियों और वर्ग विशेषताओं से संबंधित है?

+4

इसे और कब निष्पादित किया जाएगा? –

+5

@ जॉनजविनक मैं उनके भ्रम को समझ सकता था। यह सहज होगा कि वर्ग वर्ग को केवल कक्षा के पहले उदाहरण के तत्काल होने पर निष्पादित किया जाएगा (हालांकि यह मामला नहीं है)। – CoryKramer

+3

एक साधारण उत्तर - क्योंकि जिस तरह से भाषा परिभाषित की गई है .. –

उत्तर

13

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

एक क्लास बॉडी एक अलग कोड ऑब्जेक्ट का उपयोग करने का एकमात्र कारण है क्योंकि एक वर्ग निकाय को अलग नामस्थान में निष्पादित किया जाता है, उस नामस्थान के बाद कक्षा गुण बनाते हैं। कक्षा निकाय केवल ऐसे नामस्थान नहीं हैं; सेट और हथियार समझें, और पायथन 3 में, सूची समझ को अलग-अलग नामस्थान के साथ भी निष्पादित किया जाता है, जो उनके स्थानीय लोगों को स्कॉप करते हैं।

तो फ़ंक्शंस और जनरेटर एक्सप्रेशन अपवाद हैं, स्पष्ट रूप से क्योंकि उनके पूरे उद्देश्य को बाद में निष्पादित किया जाना है। ध्यान दें कि समारोह परिभाषाहै मार डाला:

>>> import dis 
>>> dis.dis(compile('def foo(): pass', '<stdin>', 'exec')) 
    1   0 LOAD_CONST    0 (<code object foo at 0x106aef2b0, file "<stdin>", line 1>) 
       3 MAKE_FUNCTION   0 
       6 STORE_NAME    0 (foo) 
       9 LOAD_CONST    1 (None) 
      12 RETURN_VALUE   

MAKE_FUNCTION बाईटकोड वहाँ बनाता समारोह वस्तु, एक साथ कि समारोह के लिए भंडारित किया बाईटकोड के साथ है, और परिणाम वैश्विक नाम foo के लिए बाध्य है।

क्लास ऑब्जेक्ट्स यहां अलग नहीं हैं; class कथन एक वर्ग वस्तु उत्पन्न करता है, और उस वस्तु के हिस्से के रूप में, हमें कक्षा निकाय के गुणों को जानने की आवश्यकता है।

यदि पायथन ने कक्षा निकाय को निष्पादित नहीं किया है, तो अन्य कोड उन वर्ग सदस्यों का कोई उपयोग नहीं कर सका।आप वर्ग विशेषताएं (वर्ग के तरीकों और स्थिर तरीकों सहित) उपयोग नहीं कर सका, तो आप वर्ग विशेषताओं, आदि

किसी भी कार्य करता है कि वर्ग शरीर का हिस्सा हैं पाठ्यक्रम नहीं कि कम से निष्पादित की हैं सेट नहीं सकता है पहर। शीर्ष-स्तरीय फ़ंक्शंस की तरह, केवल MAKE_FUNCTION बाइटकोड निष्पादित किया जाता है और परिणामी स्थानीय नाम (STORE_FAST के साथ सेट) को क्लास एट्रिब्यूट में बदल दिया जाता है, जो ग्लोबल फ़ंक्शन ऑब्जेक्ट के अनुरूप STORE_NAME के साथ वैश्विक पर बाध्य होता है।

7

Class definitions - Python documentation के अनुसार:

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

+1

साइड नोट: यह निर्दोष रूप से दिखने वाला हिस्सा: * क्लास ऑब्जेक्ट को बेस क्लास के लिए विरासत सूची और विशेषता शब्दकोश के लिए सहेजे गए स्थानीय नेमस्पेस का उपयोग करके बनाया गया है * जब कक्षा में नाम रिज़ॉल्यूशन की बात आती है तो बहुत भ्रम का स्रोत होता है विधियों ... – BartoszKP

+0

यह सिर्फ बताता है कि कक्षा निकाय वास्तव में निष्पादित किया जाता है। यह वास्तव में प्रेरित नहीं करता है * क्यों * इसे निष्पादित किया जाता है। यह एक 'कारण' जवाब है। –

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