python闭包的延迟绑定_python 闭包的延迟绑定

问题案例代码:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值