La pregunta ya ha sido respondida poraaronasterling
Sin embargo, alguien podría estar interesado en cómo se almacenan las variables bajo el capó.
Antes de llegar al fragmento:
Los cierres son funciones que heredan las variables de su entorno envolvente. Cuando pasa una devolución de llamada de función como argumento a otra función que hará E/S, esta función de devolución de llamada se invocará más tarde, y esta función recordará, casi mágicamente, el contexto en el que se declaró, junto con todas las variables disponibles en ese contexto.
Si una función no usa variables libres, no forma un cierre.
Si hay otro nivel interior que utiliza variables libres - todos niveles anteriores salvar el medio ambiente lexical (ejemplo al final)
función atributos func_closure
en pitón < 3.X o __closure__
en python> 3.X guarda las variables gratuitas.
Cada función en python tiene estos atributos de cierre, pero no guarda ningún contenido si no hay variables libres.
ejemplo: de atributos de cierre, pero no el contenido en el interior ya que no hay variable libre.
NB: FREE VARIABLE es necesidad CREAR UN CIERRE.
explicaré usando el mismo que el anterior fragmento:
>>> def make_printer(msg):
... def printer():
... print msg
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer() #Output: Foo!
y todas las funciones de Python tienen un cierre atributo de modo que vamos a examinar las variables de cerramiento asociados con una función de cierre.
Aquí es el atributo func_closure
para la función printer
>>> 'func_closure' in dir(printer)
True
>>> printer.func_closure
(<cell at 0x108154c90: str object at 0x108151de0>,)
>>>
El atributo closure
devuelve una tupla de objetos celulares que contienen detalles de las variables definidas en el ámbito circundante.
El primer elemento en el func_closure que podría ser Ninguno o una tupla de celdas que contienen enlaces para las variables libres de la función y es de solo lectura.
>>> dir(printer.func_closure[0])
['__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']
>>>
Aquí, en la salida anterior se puede ver cell_contents
, vamos a ver lo que almacena:
>>> printer.func_closure[0].cell_contents
'Foo!'
>>> type(printer.func_closure[0].cell_contents)
<type 'str'>
>>>
Así, cuando llamamos a la función printer()
, se accede al valor almacenado en el interior del cell_contents
. Así es como obtuvimos la salida como '¡Foo!'
Una vez más voy a explicar con el fragmento anterior con algunos cambios:
>>> def make_printer(msg):
... def printer():
... pass
... return printer
...
>>> printer = make_printer('Foo!')
>>> printer.func_closure
>>>
En el fragmento anterior, Me di no msg de impresión dentro de la función de impresora, por lo que no crea ninguna variable libre. Como no hay una variable libre, no habrá contenido dentro del cierre. Eso es exactamente lo que vemos arriba.
Ahora voy a explicar otro fragmento diferente para limpiar todo lo 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')
Por lo tanto, vemos que una propiedad func_closure
es una tupla de cierre células, podemos referirnos a ellos y sus contenidos explícita - una célula tiene "cell_contents" propiedad
>>> 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
>>>
Aquí cuando llamamos inn
, se referirá todo el guardar varia libre bles por lo que tenemos I am free variable
>>> inn('variable')
'I am free variable'
>>>
Curiosamente, algunos google me encontraron esto, con fecha de diciembre de 2006: http://effbot.org/zone/closure.htm. No estoy seguro, ¿los "duplicados externos" están mal visto en SO? – hbw
[PEP 227 - Ámbitos anidados estáticamente] (http://www.python.org/dev/peps/pep-0227/) para obtener más información. –