«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Как решать проблемы с областью видимости переменных в невложенных лямбда-замыканиях?

Как решать проблемы с областью видимости переменных в невложенных лямбда-замыканиях?

Опубликовано 7 ноября 2024 г.
Просматривать:201

How to Handle Variable Scoping Issues in Non-Nested Lambda Closures?

Лямбда-замыкание Python

Проблема

Инкапсуляция переменных внутри замыканий для удаления их из сигнатур функций — это метод, часто используемый для эффективного структурирования кода. Однако в случае невложенных лямбда-выражений замыкание сохраняет окончательное значение переменной, что приводит к проблемам при попытке доступа к определенным значениям на основе итерируемой переменной.

Рассмотрите предоставленный фрагмент кода:

names = ['a', 'b', 'c']

def test_fun(name, x):
    print(name, x)

def gen_clousure(name):
    return lambda x: test_fun(name, x)

funcs1 = [gen_clousure(n) for n in names]
funcs2 = [lambda x: test_fun(n, x) for n in names]

# Expected output for funcs1
for f in funcs1:
    f(1)

# Unexpected output for funcs2 (returns last element for all cases)
for f in funcs2:
    f(1)

Понимание причины этого несоответствия имеет решающее значение для эффективного использования замыканий.

Ответ

Основной концепцией в этой ситуации является определение области видимости переменных в замыканиях. . Замыкания по своей сути содержат имена переменных, а не их значения. Это означает, что оценка переменной происходит при запуске выполнения лямбды, а не во время определения лямбды.

В случае funcs2, когда вы выполняете лямбду x: test_fun(n, x), переменная n не оценивается во время определения лямбды. Вместо этого оценка происходит только при вызове лямбды. В этот момент n содержит последнее значение из цикла (в данном случае это «c»). Следовательно, функция f всегда использует «c» в качестве значения n, независимо от входных данных x.

Чтобы решить эту проблему и достичь желаемой функциональности, переменная n должна быть зафиксирована в области видимости лямбда-функции. Этого можно достичь, передав переменную в качестве аргумента в лямбду, как показано в следующем примере:

funcs2 = [lambda x: test_fun(n, x) for n in names if 2 > 0]

Включая этот дополнительный оператор if, который всегда выполняется, мы заставляем лямбду принимать значение n в качестве аргумента, обеспечивая ожидаемое персонализированное поведение во всех случаях.

Альтернатива с обернутой лямбдой

В качестве альтернативы вы можете обернуть невложенную лямбду во вложенную функцию, эффективно предотвращая доступ к необъявленным переменным в области видимости. Следующий код иллюстрирует этот подход:

def makeFunc(n):
    return lambda x: x n

stuff = [makeFunc(n) for n in [1, 2, 3]]

for f in stuff:
    print(f(1))

Здесь переменная n фиксируется в функции makeFunc, обеспечивая правильную область видимости в лямбда-выражении.

Заключение

Понимание области видимости переменных и управление ею в замыканиях необходим для эффективного проектирования и отладки кода. Ключевые выводы:

  • Замыкания хранят имена переменных, а не значения
  • Оценка переменной происходит во время выполнения лямбда-выражения
  • Чтобы захватить переменные, либо передайте их в качестве аргументов, либо оберните лямбда в другой функции
Заявление о выпуске Эта статья воспроизводится: 1729483641 Если есть какие -либо нарушения, пожалуйста, свяжитесь с [email protected], чтобы удалить его.
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3