2013-04-16 10 views
26

Let हम इस कोड है:फ़ंक्शन के अंदर फ़ंक्शन - हर बार?

def big_function(): 
    def little_function(): 
     ....... 
    ......... 

अजगर प्रलेखन कहते हैं def के बारे में बयान:

एक समारोह परिभाषा एक निष्पादन योग्य बयान है। इसके निष्पादन समारोह नाम बांधता है ...

तो, सवाल यह है: def little_function() हर बार निष्पादित करता है जब big_function शुरू होता है? प्रश्न लगभग def बयान है, little_function() शरीर नहीं।

उत्तर

30

आप dis मॉड्यूल के साथ बाईटकोड जाँच कर सकते हैं:

>>> import dis 
>>> def my_function(): 
...  def little_function(): 
...    print "Hello, World!" 
...  
... 
>>> dis.dis(my_function) 
    2   0 LOAD_CONST    1 (<code object little_function at 0xb74ef9f8, file "<stdin>", line 2>) 
       3 MAKE_FUNCTION   0 
       6 STORE_FAST    0 (little_function) 
       9 LOAD_CONST    0 (None) 
      12 RETURN_VALUE 

आप आंतरिक समारोह के लिए कोड देख सकते हैं संकलित किया गया है केवल एक बार। हर बार जब आप my_function पर कॉल करते हैं तो यह लोड हो जाता है और एक नया फ़ंक्शन ऑब्जेक्ट बनाया जाता है (इस अर्थ में def little_function हर बार my_function कहा जाता है), लेकिन यह अधिक ओवरहेड नहीं जोड़ता है।

+1

आप कैसे जानते हैं कि 'MAKE_FUNCTION' बाइट-कोड निर्देश को निष्पादित करने में कितना ओवरहेड शामिल है? ऐसा लगता है कि इसे स्मृति आवंटित करने की आवश्यकता हो सकती है जो आमतौर पर अधिकांश अन्य भाषाओं में धीमी गति से संचालन करती है। – martineau

+2

@ मार्टिनौ नहीं, कोई बड़ी स्मृति आवंटन नहीं है। 'MAKE_FUNCTION' ऑप कोड ऑब्जेक्ट के लिए संदर्भ कोड को बढ़ाता है, इसे कॉपी करने की आवश्यकता नहीं है। निश्चित रूप से एक नया फ़ंक्शन ऑब्जेक्ट बनाया गया है, जिसमें एक नया 'PyFunctionObject' आवंटित करना शामिल है लेकिन यह मानते हुए कि * हर * ऑपरेशन पायथन ऑब्जेक्ट आवंटित करता है, यह प्रदर्शन को "महत्वपूर्ण" नहीं देता है (स्पष्ट रूप से महत्वपूर्ण है' my_function के कोड के बाकी हिस्सों पर निर्भर करता है ')। – Bakuriu

+2

ग्रेट स्पष्टीकरण, धन्यवाद! – dondublon

9

आंतरिक फ़ंक्शन में कोड केवल एक बार संकलित किया जाता है, इसलिए कोई महत्वपूर्ण रनटाइम पेनल्टी नहीं होना चाहिए।

केवल आंतरिक फ़ंक्शन बंद प्रत्येक बार बाहरी फ़ंक्शन कहलाता है तो अपडेट हो जाता है। here देखें, उदाहरण के लिए, बंद होने के बारे में अधिक जानकारी के लिए।

यहाँ एक त्वरित प्रदर्शन है, बंद की जांच:

def f(x): 
    a = [] 
    b = x + 1 
    def g(): 
     print a, b 
    return g 

In [28]: y = f(5) 

In [29]: y 
Out[29]: <function __main__.g> 

In [30]: y.func_closure 
Out[30]: 
(<cell at 0x101c95948: list object at 0x101c3a3f8>, 
<cell at 0x101c958a0: int object at 0x100311aa0>) 

In [31]: y.func_closure[1].cell_contents 
Out[31]: 6 
संबंधित मुद्दे