Ámbito local, más allá del ámbito del anexo.

¿Por qué la función lambda para obtener la lista de valores i = 4? La función f ha finalizado el trabajo y ha devuelto el control (la variable i no existe).

def f(): L = [] for i in range(5): L.append(lambda x: i ** x) return L L = f() L[0] def f1(N): def f2(X): return X**N return f2 f=f1(2) f (3) 9 g = f1(3) g(3) 27 f(3) 9 

Python utiliza cierres para capturar referencias a la variable original. Los objetos lambda conservan una referencia al nombre i , a través del cual se puede acceder al valor. Esto significa que la variable i continúa viviendo después de que se complete f .

Puede realizar una introspección de este cierre en la tupla .__closure__ en los objetos lambda; Las funciones tienen el mismo atributo:

 >>> L[0].__closure__ (,) >>> L[0].__closure__[0]  >>> L[0].__closure__[0].cell_contents 4 

Esta es también la razón por la que todos los lambdas en su lista L refieren al valor 4 , y no a los números del 0 al 4. Todos se refieren al mismo cierre:

 >>> L[0].__closure__[0] is L[1].__closure__[0] True 

El cierre se refiere a la variable , no al valor de esa variable en el momento en que se definió el cierre. Al final del bucle, la última vez que la configuré fue 4 , por lo que al buscar i en el cierre lambda 4 se encontrarán todas las lambdas de su lista.

Si desea que sus lambdas se refieran al valor de i durante el bucle, capturarlo en un argumento de palabra clave:

 def f(): L = [] for i in range(5): L.append(lambda x, i=i: i ** x) return L 

Ahora i es una variable local para la lambda, no un cierre.

Alternativamente, cree un ámbito completamente nuevo desde el cual dibujar el cierre:

 def create_lambda(i): return lambda x: i ** x def f(): return [create_lambda(i) for i in range(5)] 

Ahora create_lambda() es un nuevo ámbito con su propio local i para que el cierre lambda se refiera. Cada una de las lambdas tiene sus propios cierres:

 >>> L[0].__closure__[0] is L[1].__closure__[0] False 

Los cierres se refieren a una variable en un espacio de nombres específico; cada vez que llama a una función, se crea un nuevo espacio de nombres local, por lo que cada cierre se refiere a i en create_lambda en un espacio de nombres separado de otras llamadas a create_lambda .