2015-08-26 11 views
6

तो हाल ही में मैं फ़ंक्शन क्लोजर की अवधारणा को समझता हूं।पाइथन फ़ंक्शन बंद करने का नाम बाध्यकारी कहां रखता है?

def outer(): 
    somevar = [] 
    assert "somevar" in locals() and not "somevar" in globals() 
    def inner(): 
     assert "somevar" in locals() and not "somevar" in globals() 
     somevar.append(5) 
     return somevar 
    return inner 

function = outer() 
somevar_returned = function() 
assert id(somevar_returned) == id(function.func_closure[0].cell_contents) 

जितना मैं समझता हूँ, समारोह बंद का उद्देश्य वस्तु के लिए एक सक्रिय संदर्भ रखने के लिए, आदेश में इस वस्तु का कचरा संग्रहण से बचने के लिए है। यही कारण है कि निम्नलिखित ठीक काम करता है: inner समारोह के निष्पादन से पहले (जितना मैं समझ गया हमेशा)

del outer 
somevar_returned_2 = function() 
assert id(somevar_returned) == id(function.func_closure[0].cell_contents) 
assert id(somevar_returned) == id(somevar_returned_2) 

बात है, अजगर स्थानीय लोगों चर शब्दकोश पुनर्निर्माण। इस शब्दकोश इच्छा शामिल हैं:

  • समारोह के बंद होने के नाम उनके कक्ष सामग्री से जुड़े
  • समारोह के मापदंडों उनके डिफ़ॉल्ट मान या पैरामीटर से जुड़े नाम दिया है (और यह मिसाल नाम अधिलेखित कर सकते हैं)

सवाल यह है कि पाइथन बंद होने का नाम बाध्यकारी कहां रखता है? मेरे द्वारा इसे कहीं भी ढूंढा जा सकता है।

नोट: समारोह के गुणों:

>>> print "\n".join("%-16s : %s" % (e, getattr(function, e)) for e in dir(function) if not e.startswith("_") and e != "func_globals") 
func_closure  : (<cell at 0x2b919f6bc050: list object at [...]>,) 
func_code  : <code object inner at [...], file "<stdin>", line 4> 
func_defaults : None 
func_dict  : {} 
func_doc   : None 
func_name  : inner 
+0

यकीन है कि क्या आप वास्तव में इसका मतलब यह नहीं। .. function.func_code.co_varnames'? – mata

उत्तर

5

यह अजगर कार्यान्वयन पर निर्भर करता है। मुझे लगता है कि आप सीपीथन मतलब है।

__code__ (या func_code) एक co_freevars विशेषता सभी गैर-स्थानीय चर के नाम (वे "मुक्त वार्स" कहा जाता है एक अजगर समारोह के रूप में अगर एक तार्किक सूत्र जहां तर्क और स्थानीय चर मात्रा निर्धारित कर रहे हैं था जिसमें है चर)

इन विभिन्न विशेषताओं से आप स्थानीय और गैर-स्थानीय नामों से कोशिकाओं में मैपिंग प्राप्त कर सकते हैं।

In [35]: function.__code__.co_freevars 
Out[35]: ('somevar',) 

co_varnames विशेषता को सूचीबद्ध सभी स्थानीय नामों को परिभाषित:

In [36]: function.__code__.co_varnames 
Out[36]:() 
In [37]: def outer(): 
    ...:  somevar = [] 
    ...:  def inner(): 
    ...:   x = 1 
    ...:   somevar.append(5) 
    ...:   return somevar 
    ...:  return inner 
    ...: 
    ...: function = outer() 

In [38]: function.__code__.co_varnames 
Out[38]: ('x',) 

co_cellvars कहते हैं जबकि जो स्थानीय नाम भीतरी कार्यों द्वारा किया जाता है:

In [43]: outer.__code__.co_cellvars 
Out[43]: ('somevar',) 
+0

प्रश्न का उत्तर नहीं देता है यह वास्तव में एक अच्छा जवाब है। क्या आप केवल वैध/व्याख्या कर सकते हैं कि लोकल डिक्शनरी पैरामीटर और बंद नामों से कैसे पुनर्निर्माण किया जाता है? – FunkySayu

+0

@FunkySayu मैं इसे देख रहा हूँ। ऐसा लगता है कि 'स्थानीय()' कॉल करेंगे ['PyEval_GetLocals'] (https://hg.python.org/cpython/file/tip/Python/ceval.c#l4433) जो [' PyFrame_FastToLocalsWithError'] को कॉल करता है (https: //hg.python।org/CPython/फ़ाइल/टिप/वस्तुओं/frameobject.C# l867)। जिस चीज को मैं इसके बारे में नहीं समझता वह यह है कि यह 'co_localsplus' विशेषता का संदर्भ देता है जो कि अजगर से उपलब्ध प्रतीत नहीं होता है। वैसे भी आप देख सकते हैं कि 'लोकल' शब्दकोश बनाने के लिए यह 'co_varnames',' co_freevars' आदि का उपयोग करता है। – Bakuriu

+0

शायद इसके बारे में एक और सवाल खोलना अच्छा होगा? आपका उत्तर पहले ही प्रश्न के साथ फिट है। – FunkySayu

-1
सौभाग्य से हमारे लिए

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

>>> def f(): 
...  pass 
... 
>>> repr(f); repr(f.__closure__) 
'<function f at 0x0153A330>' 
'None' 
+0

ठीक है, मुझे पता है कि सवाल यह है कि फ़ंक्शन क्लोजर से जुड़े (भविष्य) स्थानीय चर का नाम कहां है? यह पूरी तरह से – FunkySayu

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