|
12鱼币
- def count():
- fs = []
- for i in range(1, 4):
- def f():
- return i * i
- fs.append(f)
- return fs
复制代码
问题出现在使用这个函数的过程中:
有以下三种方式进行引用:
方式1,发生报错
- >>> f1 = count()
- >>> f1()
- Traceback (most recent call last):
- File "<pyshell#1>", line 1, in <module>
- f1()
- TypeError: 'list' object is not callable
复制代码
方式2,发生报错:
- >>> f1, f2 = count()
- Traceback (most recent call last):
- File "<pyshell#2>", line 1, in <module>
- f1, f2 = count()
- ValueError: too many values to unpack (expected 2)
复制代码
方式3,正常:
- >>> f3, f4, f5 = count()
- >>> f3()
- 9
复制代码
如上,问题是:
1.为什么方式1在引用的时候会报错?
2.方式2为什么在创建的时候会报错,我是没看懂报错信息
3.方式3怎么就能正常运行了?
本帖最后由 丨游戏灬需要 于 2018-11-19 23:13 编辑
1 ,f1 = count() ,但def count 的返回值是fs (是列表) ,所以报错说'列表对象
不能用"()"来"引爆"' #由于函数要加了"()"才能触发效果 ,所以我暂且称"()"为
"引爆"
2 ,报错说'太多的值以至于不能解压/分配' ,这和 a ,b =[1 ,1 ,2] ,是一种情况,
也就是说 在count()函数里 ,fs的列表里的值的个数超过了2
3 ,模拟 conut()的结果 ,在count里 ,
#里面未'引爆'的f用lambda来模拟
fs应该 = [lambda :1 *1 ,lambda :2 *2 ,lambda : 3*3]
更正一下 ,
fs储存的原来是叫做f这个函数的引用 ,所以当for循环完后 f函数的效果是:'lambda : 3*3'
实质上 ,因为函数中叫做 fs的列表 添加的是没有'引爆'的 f 函数 ,所以是 f 这个函数的引用 ,如果是'引爆'了的 ,
就变成了添加 独一的 f函数(不会因为 def f():… 而改变内部运行) (与 类对象 相似 )
也就是说 fs = [lambda : 3*3 ,lambda : 3*3 ,lambda : 3*3 ]
f3 ,f4 ,f5 分别等于fs里的 'lambda : 3*3'
所以f3'引爆'后等于 运行了return3*3
补充:
如果要用闭包实现 fs = [lambda :1 *1 ,lambda :2 *2 ,lambda : 3*3] (里面的lambda同样只是代指效果不是真实lambda)的话 ,代码应该这样改:
1 :fs.append(f) 中的 f 必须要'引爆'(成为单独的个体) ,
2 为了列表里的对象可以'引爆' , f的返回值必须是函数(def 或 lambda) ,
3 '个体'要保存有具体的值 ,而不是对外部的引用
其中第二点和第三点的结合 应该 才是闭包? 也就是说 f才是闭包函数 count不是…
例如:
def count():
fs = []
for i in range(1, 4):
def f():
arg =i #这句是为了让 arg 变为 f函数内部的值 ,而不是默认用 i的引用 or 如下
def f2(): #指 内部arg变量的值 等于 外部 i的值 (i 得是单个值(或独立的类实例) ,而不能是序列(类对象) ,否则arg也只能是个引用(会影响其他的引用))
return arg * arg
return f2
fs.append(f())
return fs
f1 ,f2 ,f3 = count() #f1() = 1 ,f2() = 4 ,f3() = 9
|
最佳答案
查看完整内容
1 ,f1 = count() ,但def count 的返回值是fs (是列表) ,所以报错说'列表对象
不能用"()"来"引爆"' #由于函数要加了"()"才能触发效果 ,所以我暂且称"()"为
"引爆"
2 ,报错说'太多的值以至于不能解压/分配' ,这和 a ,b =[1 ,1 ,2] ,是一种情况,
也就是说 在count()函数里 ,fs的列表里的值的个数超过了2
3 ,模拟 conut()的结果 ,在count里 ,
#里面未'引爆'的f用lambda来模拟
fs应该 = [lambda :1 *1 ,lambda :2 *2 ,lambd ...
|