प्रश्न का उत्तर पहले ही aaronasterling द्वारा दिया जा चुका है
हालांकि, किसी को दिलचस्पी हो सकती है कि हुड के नीचे चर कैसे संग्रहीत किए जाते हैं।
स्निपेट में आने से पहले:
क्लोजर वे फ़ंक्शंस हैं जो वैरिएबल को उनके संलग्न वातावरण से विरासत में मिलते हैं। जब आप एक फ़ंक्शन कॉलबैक को किसी अन्य फ़ंक्शन के तर्क के रूप में पास करते हैं जो I / O करेगा, तो यह कॉलबैक फ़ंक्शन बाद में लागू किया जाएगा, और यह फ़ंक्शन होगा - लगभग जादुई रूप से - उस संदर्भ को याद रखें जिसमें यह घोषित किया गया था, साथ ही सभी चर उपलब्ध उस संदर्भ में।
यदि कोई फ़ंक्शन फ्री वैरिएबल का उपयोग नहीं करता है तो यह क्लोजर नहीं बनता है।
यदि कोई अन्य आंतरिक स्तर है जो मुफ्त चर का उपयोग करता है - पिछले सभी स्तर शाब्दिक वातावरण को बचाते हैं (उदाहरण के अंत में)
pythonfunc_closure
में फ़ंक्शन विशेषताएँ <3.X या __closure__
python> 3.X में मुक्त चर बचाते हैं।
अजगर के हर फंक्शन में यह क्लोजर गुण होते हैं, लेकिन अगर कोई फ्री वैरिएबल नहीं है तो यह किसी भी कंटेंट को सेव नहीं करता है।
उदाहरण: क्लोजर विशेषताएँ लेकिन अंदर कोई सामग्री नहीं है क्योंकि कोई मुफ्त चर नहीं है।
>>> def foo():
... def fii():
... pass
... return fii
...
>>> f = foo()
>>> f.func_closure
>>> 'func_closure' in dir(f)
True
>>>
नायब: नि : शुल्क वैरिएबल एक ग्राहक बनाने के लिए आवश्यक है।
मैं ऊपर के समान स्निपेट का उपयोग करके समझाऊंगा:
>>> def make_printer(msg):
... def printer():
... print msg
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer() #Output: Foo!
और सभी पायथन फ़ंक्शन में एक क्लोजर विशेषता होती है, तो चलो एक क्लोजर फ़ंक्शन के साथ जुड़े एन्कोडिंग चर की जांच करते हैं।
यहाँ func_closure
फ़ंक्शन के लिए विशेषता हैprinter
>>> 'func_closure' in dir(printer)
True
>>> printer.func_closure
(<cell at 0x108154c90: str object at 0x108151de0>,)
>>>
closure
विशेषता सेल वस्तुओं जो चर संलग्न दायरे में परिभाषित के विवरण शामिल की एक टपल देता है।
फंक_क्लोजर में पहला तत्व जो कोई नहीं हो सकता है या कोशिकाओं का एक समूह हो सकता है जिसमें फ़ंक्शन के मुक्त चर के लिए बाइंडिंग होती है और यह केवल पढ़ने के लिए होती है।
>>> dir(printer.func_closure[0])
['__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']
>>>
यहाँ उपरोक्त आउटपुट में आप देख सकते हैं cell_contents
, देखते हैं कि यह क्या स्टोर करता है:
>>> printer.func_closure[0].cell_contents
'Foo!'
>>> type(printer.func_closure[0].cell_contents)
<type 'str'>
>>>
इसलिए, जब हमने फ़ंक्शन को कॉल किया printer()
, तो यह अंदर संग्रहीत मान तक पहुंचता है cell_contents
। इसी से हमें आउटपुट 'फू' के रूप में मिला है।
फिर मैं कुछ बदलावों के साथ उपरोक्त स्निपेट का उपयोग करके समझाऊंगा:
>>> def make_printer(msg):
... def printer():
... pass
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer.func_closure
>>>
उपरोक्त स्निपेट में, मैं प्रिंटर फ़ंक्शन के अंदर संदेश प्रिंट नहीं कर सकता, इसलिए यह कोई भी मुफ्त चर नहीं बनाता है। जैसा कि कोई फ्री वैरिएबल नहीं है, क्लोजर के अंदर कोई कंटेंट नहीं होगा। जैसा हम ऊपर देखते हैं वैसा ही है।
अब मैं सब कुछ बाहर खाली करने के लिए एक और अलग टुकड़ा समझा जाएगा Free Variable
साथ Closure
:
>>> def outer(x):
... def intermediate(y):
... free = 'free'
... def inner(z):
... return '%s %s %s %s' % (x, y, free, z)
... return inner
... return intermediate
...
>>> outer('I')('am')('variable')
'I am free variable'
>>>
>>> inter = outer('I')
>>> inter.func_closure
(<cell at 0x10c989130: str object at 0x10c831b98>,)
>>> inter.func_closure[0].cell_contents
'I'
>>> inn = inter('am')
इसलिए, हम देखते हैं कि एक func_closure
संपत्ति क्लोजर कोशिकाओं का एक समूह है , हम उन्हें और उनकी सामग्री को स्पष्ट रूप से संदर्भित कर सकते हैं - एक सेल में संपत्ति "cell_contents" है
>>> inn.func_closure
(<cell at 0x10c9807c0: str object at 0x10c9b0990>,
<cell at 0x10c980f68: str object at 0x10c9eaf30>,
<cell at 0x10c989130: str object at 0x10c831b98>)
>>> for i in inn.func_closure:
... print i.cell_contents
...
free
am
I
>>>
यहां जब हमने कॉल किया inn
, तो यह सभी सेव फ्री वैरिएबल को संदर्भित करेगा ताकि हम प्राप्त करेंI am free variable
>>> inn('variable')
'I am free variable'
>>>