"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como lidar com problemas de escopo de variáveis ​​em fechamentos Lambda não aninhados?

Como lidar com problemas de escopo de variáveis ​​em fechamentos Lambda não aninhados?

Publicado em 2024-11-07
Navegar:987

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

Python Lambda Closure Scoping

Problema

Encapsular variáveis ​​​​dentro de encerramentos para removê-las das assinaturas de função é uma técnica frequentemente usada para estruturação de código eficiente. No entanto, no caso de lambdas não aninhados, o fechamento retém o valor final da variável, levando a problemas ao tentar acessar valores específicos com base na variável iterativa.

Considere o snippet de código fornecido:

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)

Compreender a razão por trás dessa discrepância é crucial para a utilização eficaz do fechamento.

Resposta

O conceito fundamental nesta situação é escopo variável nos fechamentos . Os fechamentos contêm inerentemente os nomes das variáveis em vez de seus valores. Isso significa que a avaliação da variável ocorre quando a execução do lambda é iniciada, e não no momento da definição do lambda.

No caso de funcs2, quando você executa lambda x: test_fun(n, x), a variável n não é avaliado durante a definição de lambda. Em vez disso, a avaliação só acontece na chamada lambda. Nesse ponto, n contém o último valor do loop (que é 'c' neste caso). Consequentemente, a função f sempre utiliza 'c' como o valor de n, independentemente da entrada x.

Para resolver esse problema e obter a funcionalidade desejada, a variável n deve ser capturada no escopo da função lambda. Isso pode ser conseguido passando a variável como um argumento para o lambda, conforme mostrado a seguir:

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

Ao incluir esta instrução if adicional que sempre é verdadeira, forçamos o lambda a tomar o valor de n como argumento, garantindo o comportamento personalizado esperado em todos os casos.

Alternativa com Wrapped Lambda

Como alternativa, você pode agrupar o lambda não aninhado em uma função aninhada, evitando efetivamente o acesso a variáveis ​​não declaradas no escopo. O código a seguir ilustra essa abordagem:

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

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

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

Aqui, a variável n é capturada na função makeFunc, garantindo o escopo adequado dentro do lambda.

Conclusão

Compreendendo e gerenciando o escopo da variável em encerramentos é essencial para design e depuração de código eficazes. As principais conclusões são:

  • Os fechamentos contêm nomes de variáveis, não valores
  • A avaliação de variáveis ​​ocorre durante a execução do lambda
  • Para capturar variáveis, passe-as como argumentos ou envolva-as o lambda em outra função
Declaração de lançamento Este artigo foi reimpresso em: 1729483641 Se houver alguma violação, entre em contato com [email protected] para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3