为了账号安全,请及时绑定邮箱和手机立即绑定

python闭包的问题

# 希望一次返回3个函数,分别计算1x1,2x2,3x3:
def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs

f1, f2, f3 = count()

请教一下为什么返回的是三个函数?

我的理解count函数返回的是 list fs[],而循环for i in range(1,4)中 fs.append(f)执行了三次(分别i=1\2\3),

那么fs.append(f)后,fs中保存的是函数名f 还函数f()的返回值i*i? 

可是在循环结束我print fs结果为[, , ]。可见append()方法执行了,但为什么添加的内容却为空?


示例说:

由于f1、f2、f3并没有被调用,所以,此时他们并未计算 i*i,当 f1 被调用时:

>>> f1()
9     # 因为f1现在才计算i*i,但现在i的值已经变为3

  如果这样的话fs[]中保存的就应该是函数名吧!?但还是不理解print fs结果为[, , ],而且print f1也是''

难道发fs[]中保存的哪种不能输出的数据?

print count

lst = count()

print lst

lst.append(count)

print lst

输出结果为

[, , ]
[, , , ]

print count 没有输出,可见fs[]中的确保存的是一种关联‘函数名‘的数据,有点像c中的指针,但是这种数据不能通过print输出?!

如果这样的话for 循环中每次def f()虽然名称相同但是实际还是不同,但是python中能够有重名的函数?

试了一下python中的确可以有命名相同的函数,但是看效果应该是后面的函数覆盖了前面的函数。如果这样的话前面虽然fs[]中保存了三个函数但是实际上有效的就是最后一个,此时i=3.倒也符合

def count():

    fs = []

    for i in range(1, 4):

        def f(i):

             return i*i

        fs.append(f(i))

    print fs

    return fs

这里的输出却是[1,4,9],也就是说fs保存的是函数的f(i)的返回值。。。到这里我已经懵逼了...这里是我搞混了即使是f(i),f才是函数名,f(i)是直接调用函数,  fs.append(f(i))本身就有问题


正在回答

1 回答

你的描述看了一部分,感觉你已经完全被绕晕了。所以不针对你的提问一一回答,只说一下我觉得正确的理解,你可以看完后跑一下,我没有跑不保证每处细节都正确。

首先,fs 是一个 list,只不过其中的元素不是数字而是函数。也就是说(fs[0])(),是可以调用该函数的。另外,i 的作用域实在count函数内的,所以当延迟调用 fs 里的任意函数时,去寻找 i 的值时,i 已经变成了 3。所以所有的结果都是9。另外 f1, f2, f3 = count(),是结构赋值语句,也就是说 f1 是 fs 里的第一个函数。f1 == fs[0]

2 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
python进阶
  • 参与学习       255665    人
  • 解答问题       2949    个

学习函数式、模块和面向对象编程,掌握Python高级程序设计

进入课程

python闭包的问题

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信