问题案例代码:
def func(n):
lt = []
for i in range(n):
def late(x):
return x*i
lt.append(late)
return lt
f0,f1,f2,f3 = func(4)
print([type(f0),type(f1),type(f2),type(f3)])
print([f0(10),f1(10),f2(10),f3(10)])
#运行结果
[, , , ]
[30, 30, 30, 30]
Process finished with exit code 0
怎么结果完全一样呢?看到这的肯定一脸懵比像。仔细看代码,函数func()返回的应该是一个列表,列表中的元素应该是函数late()的运算结果,因为循环i是变动的,所以预期的结果应该是[0,10,20,30]。但是运算结果却不是这样。到底哪里出错了呢,再看看x与i的值。修改一下代码,打印输出一下x与i看看:
def func(n):
lt = []
for i in range(n):
def late(x):
print(x,i)
return x*i
lt.append(late)
return lt
f0,f1,f2,f3 = func(4)
print('f0: ',f0(10))
print('f1: ',f1(10))
print('f2: ',f2(10))
print('f3: ',f3(10))
10 3
f0: 30
10 3
f1: 30
10 3
f2: 30
10 3
f3: 30
Process finished with exit code 0
看看输出结果,参数10就不用看了,来看看i,嗯?为什么i输出都是3,不应该啊,循环没错啊,不理解,真是不理解。
不理解怎么办?有问题找百度啊,下面是我找的两篇相关资料文章,感兴趣的可以看看哦。
参考1 参考2
总结一下(借鉴一下):
python里, 非局部变量绑定的是空间, 而不是值本身,所以,生成的函数i, 相对于函数f 来说, 是全局变量, 所以绑定的是 i 所在的内存地址.所以导致了,生成的四个函数所得值时相同的.
由于闭包函数引用的外部作用域的自由变量, 只有在内部函数被调用的时候才会搜索变量m的值
在函数嵌套中,内部函数引用时使用的参数如果从外部动态调用,一定要将该参数的值(不是内存地址)传入内部函数中
修改函数:
def func(n):
lt = []
for i in range(n):
def late(x,i=i): #每次生成函数, i的值, 都被绑定到函数本身 ,相当于给每个函数一个默认参数
print(x,i)
return x*i
lt.append(late)
return lt
f0,f1,f2,f3 = func(4)
print('f0: ',f0(10))
print('f1: ',f1(10))
print('f2: ',f2(10))
print('f3: ',f3(10))
#运行结果
10 0
f0: 0
10 1
f1: 10
10 2
f2: 20
10 3
f3: 30
Process finished with exit code 0
链接一问题解答:
def multipliers(n):
funcs = []
for i in range(n):
def f(*arg,i=i): # *arg 传入的是元组
print(arg, '*' ,i, '=')
return arg * i
funcs.append(f)
return funcs
g0, g1, g2, g3 = multipliers(4)
print(g0(10))
print(g1(10))
print(g2(10))
print(g3(10))
#运行结果
(10,) * 0 =
()
(10,) * 1 =
(10,)
(10,) * 2 =
(10, 10)
(10,) * 3 =
(10, 10, 10)
Process finished with exit code 0