Неверное закрытие в лямбда-функции Python - PullRequest
3 голосов
/ 28 июня 2019

Рассмотрим этот фрагмент кода:

class X:
    pass

xs = []
for s in ("one", "two", "three"):
    x = X()
    x.f = lambda: print(s)
    xs.append(x)

for x in xs:
    x.f()

Выходные данные:

three
three
three

Это действительно ожидаемое поведение? Не могли бы вы объяснить, почему это не так:

one
two
three

Ответы [ 2 ]

2 голосов
/ 28 июня 2019

Это происходит потому, что переменная s является ссылкой, а не значением.И значение по ссылке будет разрешено, когда оно будет вызвано, а не создано.Чтобы определить значение во время создания, используйте default argument.

lambda s=s: print(s)
2 голосов
/ 28 июня 2019

Ваша лямбда-функция содержит ссылку на s, следовательно, последнее присвоенное значение s печатается при вызове вне цикла for. Попробуйте приведенный ниже код для вашего ожидаемого поведения. Здесь копия этой существующей ссылки s создается в v в качестве аргумента функции, и это значение печатается внутри функции f.

class X:
    pass

xs = []
for s in ("one", "two", "three"):
    x = X()
    def f(v=s): print(v)
    x.f = f
    xs.append(x)

for x in xs:
    x.f()

Выход:

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