python函数闭包的理解

查询了DeepSeek, 给出如下面试踩坑代码,输出结果是 2 2 2 

******************************************************************
funcs = []
for i in range(3):
    def inner():
        return i
    funcs.append(inner)

for f in funcs:
    print(f())  # 你期望输出 0, 1, 2 对吗?
# 实际输出: 2, 2, 2

*************************************************************

DeepSeek的详细解释如下:

1. def 是“声明”而非“执行”:def func(): 这行语句的作用是创建一个函数对象并将其赋值给变量 func,此时函数体内的代码纹丝未动。

2. () 是“执行”的扳机:只有在代码中显式写上 func() 时,Python 才会跳转到之前定义好的函数体内部,开始执行里面的代码。

3. 解释型语言的特征:Python作为解释型语言,是逐行解释执行的。它必须先“看到”或“定义”一个函数,才能后续调用它。

从上面的代码可以看到,代码段def inner()在for循环内,说明for循环执行时,inner函数被创建了三个函数对象,
代码段funcs.append(inner)中,inner没有加括号,说明在for循环体内,inner函数没有被执行。
()出现在第一个for循环结束,在第二个for循环中,inner函数才开始被执行,这个时候第一个for循环已经结束了,变量i的值已经变成了2,所以打印输出值为2 2 2 

for f in funcs:
    print(f()) 

根据上面的理解我修改代码如下,将()加在代码行funcs.append(inner())中,将第二个for循环中()括号去掉 print(f) ,这样inner函数就会在第一个for循环体内执行,

第一种解法:

************************************************************
funcs = []
for i in range(3):
    def inner():
        return i
    funcs.append(inner())

for f in funcs:
    print(f)  # 你期望输出 0, 1, 2 对吗?

*********************************************************
测试结果得出期望值0 1 2

第二种解法:利用默认参数或另一个函数来“冻结”当前值。

# 方法1:使用默认参数(立即求值)
for i in range(3):
    def inner(x=i):  # 默认参数在函数定义时就被求值并固定了
        return x
    funcs.append(inner)

def make_inner(j):
    def inner():
        return j  # 此时j来自make_inner,它在每次循环中被单独创建
    return inner
for i in range(3):
    funcs.append(make_inner(i))
全部评论

相关推荐

卡卡罗特ovo:说起云智我就来气,约好了一面,结果面试官没来,ssob上问hr也未读,我还是专门请了半天假在家面试,恶心死了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务