Create functions dynamically within a loop but appear to have the same behavior?

本文解释了在Python中,由于闭包特性,动态创建的函数会共享循环变量的最终值。提供了使用默认参数和函数工厂两种方法来避免这个问题,确保每个函数使用的是其定义时的变量值。
摘要由CSDN通过智能技术生成
DateAuthorVersionNote
2024.02.02Dog TaoV1.0Release as V1.0

This article is published in CSDN

Introduction

When dynamically creating functions within a loop in Python, if each function is defined to use a variable that changes in each iteration of the loop (like the loop variable itself), all functions might end up behaving like the last function created. This happens due to a common pitfall known as the “late binding closure” issue. Essentially, the functions capture and share the same variable, not its value at the time of the function’s definition, but its final value after the loop has completed.

Why does this happen?

In Python, closures—functions defined inside another function—capture variables by reference, not by value. This means that a function defined inside a loop captures a reference to the loop variable, not a snapshot of its value at the time the function is defined. When the loop variable changes, the change is reflected in all functions that reference this variable, making it seem as if all functions are using the last value of the loop variable.

Example Illustration

Consider the following example where we create a list of functions in a loop, each supposed to print a different number:

functions = []
for i in range(3):
    functions.append(lambda: print(i))

for f in functions:
    f()  # Expecting to print 0, 1, 2 but prints 2, 2, 2

All functions print 2, the last value of i, because they all reference the same i variable, which ends up being 2 after the loop ends.

How to Fix This

To avoid this issue, you can define your functions using default arguments, which capture the value at the time the function is defined, not the reference:

functions = []
for i in range(3):
    functions.append(lambda i=i: print(i))  # Using default arguments to capture the current value of i

for f in functions:
    f()  # This will correctly print 0, 1, 2

Another common approach is to use a function factory that generates functions, capturing the current state of variables:

def make_function(i):
    return lambda: print(i)

functions = []
for i in range(3):
    functions.append(make_function(i))  # Using a factory function to capture the current value of i

for f in functions:
    f()  # This will correctly print 0, 1, 2

Both of these solutions ensure that the value of i at the time of each function’s creation is captured and used, rather than the final value of i after the loop has finished.

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全能骑士涛锅锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值