Soru zaten aaronasterling tarafından cevaplandı
Bununla birlikte, birisi değişkenlerin kaputun altında nasıl saklandığıyla ilgilenebilir.
Snippet'e gelmeden önce:
Kapaklar, değişkenleri çevreleyen ortamlarından devralan işlevlerdir. Bir fonksiyon geri aramasını G / Ç yapacak başka bir fonksiyona argüman olarak ilettiğinizde, bu geri arama fonksiyonu daha sonra çağrılır ve bu fonksiyon - neredeyse sihirli bir şekilde - mevcut tüm değişkenlerle birlikte bildirildiği bağlamı hatırlar bu bağlamda.
Bir işlev serbest değişkenler kullanmıyorsa, bir kapatma oluşturmaz.
Serbest değişkenler kullanan başka bir iç seviye varsa - önceki tüm seviyeler sözlük ortamını korur (örnek sonunda)
fonksiyon nitelikleri func_closure
de piton <3.X veya __closure__
serbest değişkenler tasarrufu python> 3.X.
Python'daki her işlevin bu kapatma öznitelikleri vardır, ancak serbest değişken yoksa herhangi bir içerik kaydetmez.
örnek: closure öznitelikleri, ancak serbest değişken olmadığı için içeride içerik yok.
>>> def foo():
... def fii():
... pass
... return fii
...
>>> f = foo()
>>> f.func_closure
>>> 'func_closure' in dir(f)
True
>>>
NOT: ÜCRETSİZ DEĞİŞİM KAPANIŞ OLMALIDIR.
Yukarıdaki pasajı kullanarak açıklayacağım:
>>> def make_printer(msg):
... def printer():
... print msg
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer() #Output: Foo!
Ve tüm Python işlevlerinin bir kapatma özelliği vardır, bu yüzden bir kapatma işleviyle ilişkili çevreleyen değişkenleri inceleyelim.
İşte func_closure
işlevin özniteliğiprinter
>>> 'func_closure' in dir(printer)
True
>>> printer.func_closure
(<cell at 0x108154c90: str object at 0x108151de0>,)
>>>
closure
Özelliği, parça kapsamında tanımlanan değişken ayrıntılarını içeren hücre nesnelerin bir demet döndürür.
Func_closure içinde None ya da işlevin serbest değişkenleri için bağlar içeren bir hücre dizisi olan ve salt okunur olan ilk öğe.
>>> dir(printer.func_closure[0])
['__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']
>>>
Yukarıdaki çıktıda görebildiğiniz gibi cell_contents
, ne depoladığını görelim:
>>> printer.func_closure[0].cell_contents
'Foo!'
>>> type(printer.func_closure[0].cell_contents)
<type 'str'>
>>>
Bu nedenle, işlevi çağırdığımızda, printer()
içinde saklanan değere erişir cell_contents
. Bu şekilde 'Foo!'
Yine yukarıdaki pasajı bazı değişikliklerle kullanmayı açıklayacağım:
>>> def make_printer(msg):
... def printer():
... pass
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer.func_closure
>>>
Yukarıdaki snippet'te, msg'yi yazıcı işlevinin içine yazdırmıyorum, bu yüzden herhangi bir serbest değişken oluşturmuyor. Serbest değişken olmadığından, kapak içinde içerik olmayacaktır. Bu tam olarak yukarıda gördüğümüz şey.
Şimdi her şeyi temizlemek için başka farklı parçacığını açıklayacağız Free Variable
ile 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')
Yani, bir func_closure
özelliğin bir dizi kapatma hücresi olduğunu görüyoruz görüyoruz, onları ve içeriklerini açıkça ifade edebiliriz - bir hücrenin "cell_contents" özelliği vardır
>>> 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
>>>
Burada aradığımızda inn
, tüm kaydedilmiş serbest değişkenleri gösterecektir, böyleceI am free variable
>>> inn('variable')
'I am free variable'
>>>