лямбда-функция не закрывает параметр в Python? - PullRequest
9 голосов
/ 22 сентября 2011

Код говорит больше:


from pprint import pprint

li = []

for i in range(5):
        li.append(lambda : pprint(i))

for k in li:
        k()

выход:

4
4
4
4
4

почему бы и нет

0
1
2
3
4

??

Спасибо.

P.S. Если я напишу полный декоратор, он будет работать как положено:



from pprint import pprint

li = []

#for i in range(5):
        #li.append(lambda : pprint(i))

def closure(i):
        def _func():
                pprint(i)
        return _func

for i in range(5):
        li.append(closure(i))

for k in li:
        k()

Ответы [ 5 ]

11 голосов
/ 22 сентября 2011

вам нужно сделать:

lambda i=i: pprint(i)

вместо того, чтобы зафиксировать текущее значение i

3 голосов
/ 22 сентября 2011

Если вы не хотите использовать аргумент по умолчанию - который может привести к ошибкам при случайном вызове с аргументом - вы можете использовать вложенную лямбду:

from pprint import pprint

li = []

for i in range(5):
    li.append((lambda x: lambda: pprint(x))(i))

for k in li:
    k()

Это анонимная версияваша closure функция.

3 голосов
/ 22 сентября 2011

Правильно ссылается на i, единственное, что к тому времени, когда ваш список будет заполнен, i будет иметь значение, назначенное из последнего элемента в последовательности, когда итерация закончилась, поэтому вы видите 4 все кончено.

0 голосов
/ 22 сентября 2011

Ответ: поскольку код внутри лямбды использует вашу глобальную переменную i.

Ваш второй вариант будет аналогичен первому варианту с лямбда, если удалить параметр i:

def closure():

Вместо

def closure(i):

Т.е. код внутри функции будет использовать глобальную переменную i.

0 голосов
/ 22 сентября 2011

Лямбда-функции создают замыкания над переменной i. После завершения первого цикла for значение i 4.

Затем запускается второй цикл for и выполняются все лямбда-функции. Затем каждый из них печатает текущее значение i, которое равно 4.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...