在循环中创建函数:解决后期绑定问题
尝试在循环中定义单个函数时,通常会遇到以下问题:尽管旨在表示唯一的结果,但所有函数都返回相同的值。这种现象称为后期绑定,发生的原因是函数在被调用之前不会接收其参数。
考虑以下使用 for 循环的示例:
functions = [] for i in range(3): def f(): return i functions.append(f)
如所写,每个函数在调用时查找 i 的相应值。然而,循环执行后,所有函数都将引用 i (2) 的最终值,从而产生以下输出:
print([f() for f in functions]) # Expected: [0, 1, 2] # Actual: [2, 2, 2]
解决方案:强制早期绑定
为了解决这个问题,有必要通过在定义时而不是调用时将参数分配给函数来强制早期绑定。这可以通过在函数定义中添加默认参数来实现:
functions = [] for i in range(3): def f(i=i): return i functions.append(f)
默认参数(在本例中为 i=i)在定义函数时计算,而不是在调用函数时计算。这确保每个函数保留其唯一的参数值,产生所需的输出:
print([f() for f in functions]) # Output: [0, 1, 2]
使用闭包的替代方法
如果担心可能存在其他参数要传递给函数,可以使用闭包实现更复杂的方法:
def make_f(i): def f(): return i return f
在这种情况下,创建函数工厂 (make_f)。在循环内,make_f 返回的函数被分配给 f 变量,而不是直接调用 def f():。这种方法保证每个函数保留其独占的参数值,就像早期的绑定解决方案一样。
以上是为什么循环中定义的函数经常返回相同的值,如何解决这个问题?的详细内容。更多信息请关注PHP中文网其他相关文章!