"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ¿Cómo evitar el comportamiento inesperado en el alcance de la función lambda y los parámetros en los bucles?

¿Cómo evitar el comportamiento inesperado en el alcance de la función lambda y los parámetros en los bucles?

Publicado el 2025-03-24
Navegar:267

How to Avoid Unexpected Behavior in Lambda Function Scope and Parameters in Loops?

alcance de las funciones lambda y sus parámetros

lambda funciones, introducidas en python como funciones anónimas concisas, ofrecen conveniencia en varios escenarios. Sin embargo, comprender su alcance de parámetros puede ser crucial para evitar un comportamiento inesperado. Exploremos un problema común que surge cuando se usa funciones lambda dentro de loops.

el problema

considere el siguiente código, que tiene como objetivo crear una lista de funciones de devolución de llamada para eventos GUI:

def callback(msg):
    print msg

# Incorrect approach using an iterator
funcList = []
for m in ('do', 're', 'mi'):
    funcList.append(lambda: callback(m))

# Correct approach creating one at a time
funcList = []
funcList.append(lambda: callback('do'))
funcList.append(lambda: callback('re'))
funcList.append(lambda: callback('mi'))

# Execute the callback functions
for f in funcList:
    f()

Cuando se ejecuta, el código imprime inesperadamente:

mi
mi
mi
do
re
mi

en lugar de la salida esperada:

do
re
mi
do
re
mi

la explicación

comprender el alcance de las funciones lambda y sus parámetros es crucial aquí. A diferencia de las funciones regulares, las funciones de Lambda hacen referencia al entorno circundante en el que se crean. Esta referencia incluye variables utilizadas dentro del cuerpo de Lambda.

Cuando se usa un iterador en el enfoque incorrecto, para cada elemento m en el bucle, crea una nueva función lambda que hace referencia a la misma variable m. Sin embargo, después de que se completa el bucle, la variable m hace referencia al último elemento en el bucle, es decir, 'mi'. Por lo tanto, cuando las funciones de devolución de llamada se ejecutan, todos imprimen 'mi' usando la referencia actualizada.

la solución

para resolver este problema, podemos capturar el valor del parámetro M en el momento en que la función lambda se crea mediante el uso de it como argumento predeterminado de un parámetro opcional:

[&] 're', 'mi'): FunClist.Append (lambda m = m: callback (m))
for m in ('do', 're', 'mi'):
    funcList.append(lambda m=m: callback(m))
ahora, dentro de cada función lambda, m se captura como una variable local, y su valor se conserva cuando el bucle se completa. En consecuencia, cuando las funciones de devolución de llamada se ejecutan, imprimen los valores correctos, lo que resulta en la salida esperada.

Declaración de liberación Este artículo se reproduce en: 1729329977 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3