La questione è già stato risposto conaaronasterling
Tuttavia, qualcuno potrebbe essere interessato a come le variabili sono memorizzate sotto il cofano.
Prima di arrivare al frammento:
chiusure sono funzioni che ereditano le variabili dal loro ambiente che racchiude. Quando si passa una funzione callback come argomento a un'altra funzione che eseguirà I/O, questa funzione di callback verrà richiamata in un secondo momento e questa funzione - quasi magicamente - ricorderà il contesto in cui è stata dichiarata, insieme a tutte le variabili disponibili in quel contesto.
Se una funzione non utilizza variabili libere, non forma una chiusura.
Se c'è un altro livello interno che utilizza variabili libere - tutti livelli precedenti salvare l'ambiente lessicale (esempio alla fine)
funzione attributi func_closure
in pitone < 3.X o __closure__
in python> 3.X salva le variabili libere.
Ogni funzione in python ha questi attributi di chiusura, ma non salva alcun contenuto se non ci sono variabili libere.
esempio: di attributi di chiusura ma non contenuto all'interno quanto non v'è alcuna variabile libera.
NB: FREE VARIABLE è necessario per CREARE UNA CHIUSURA.
spiegherò usando lo stesso frammento di codice di cui sopra:
>>> def make_printer(msg):
... def printer():
... print msg
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer() #Output: Foo!
e tutte le funzioni in Python hanno una chiusura attributo Quindi cerchiamo di esaminare le variabili di cinta associati a una funzione di chiusura.
Ecco l'attributo func_closure
per la funzione printer
>>> 'func_closure' in dir(printer)
True
>>> printer.func_closure
(<cell at 0x108154c90: str object at 0x108151de0>,)
>>>
L'attributo closure
restituisce una tupla di oggetti cellulari che contengono dettagli delle variabili definite nell'ambito racchiude.
Il primo elemento nella func_closure che potrebbe essere None o una tupla di celle che contengono binding per le variabili libere della funzione ed è di sola lettura.
>>> dir(printer.func_closure[0])
['__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']
>>>
Qui nell'output sopra potete vedere cell_contents
, vediamo cosa memorizza:
>>> printer.func_closure[0].cell_contents
'Foo!'
>>> type(printer.func_closure[0].cell_contents)
<type 'str'>
>>>
Così, quando abbiamo chiamato la funzione printer()
, si accede al valore memorizzato all'interno del cell_contents
. Ecco come abbiamo ottenuto l'output come "Foo!"
Ancora una volta vi spiegherò utilizzando il frammento di cui sopra con alcune modifiche:
>>> def make_printer(msg):
... def printer():
... pass
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer.func_closure
>>>
Nel frammento di cui sopra, ho din't msg di stampa all'interno della funzione di stampa, in modo che non crea alcun variabile libera. Dato che non ci sono variabili libere, non ci sarà contenuto all'interno della chiusura. Questo è esattamente ciò che vediamo sopra.
Ora vi spiegherò un altro frammento di diverso per cancellare tutto Free Variable
con 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')
Quindi, vediamo che una proprietà func_closure
è una tupla di chiusura cellule, siamo in grado di loro e il loro contenuto si riferiscono esplicitamente - una cellula ha proprietà "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
>>>
Qui quando abbiamo chiamato inn
, si farà riferimento tutta la varia gratis Bles in modo da ottenere I am free variable
>>> inn('variable')
'I am free variable'
>>>
È interessante notare che alcuni googling mi hanno trovato questo, datato dicembre 2006: http://effbot.org/zone/closure.htm. Non sono sicuro-sono "duplicati esterni" disapprovati su SO? – hbw
[PEP 227 - Scope nidificate staticamente] (http://www.python.org/dev/peps/pep-0227/) per ulteriori informazioni. –