在python闭包中使用其他命名空间的变量(关于python闭包和变量的命名空间)

关于python闭包和变量的命名空间

例子

例子1

def create_multipliers():
return [lambda x : i * x for i in range(5)]

for multiplier in create_multipliers():
print(multiplier(2))

输出

8
8
8
8
8

例子2

def create_multipliers2():
multipliers = []
for i in range(5):
def multiplier(x):
return i * x
multipliers.append(multiplier)
return multipliers

for multiplier in create_multipliers2():
print(multiplier(2))

输出

8
8
8
8
8

例子3

func_list = []
for i in range(10):
def callback():
print(“clicked button”, i)
func_list.append(callback)

for func in func_list:
func()

输出

clicked button 4
clicked button 4
clicked button 4
clicked button 4
clicked button 4

##分析
原因都一样,只针对例子2进行分析。
在函数create_multipliers2中,返回了一个列表,列表中每个成员都是一个函数multiplier,该函数需要一个参数x,函数返回值是x 乘以 i。
其中,变量x是multiplier的参数,也就是函数multiplier的局部变量,所以变量x的命名空间是函数multiplier。
变量i是create_multipliers2的变量,所以变量i的命名空间是函数create_multipliers2。
在执行print(multiplier(2))时,函数create_multipliers2的变量i已经变成了4。
所以,一直打印8。

解决方法

例子2

方案1:yield

def create_multipliers2():
for i in range(5):
def multiplier(x):
return i * x
yield multiplier

for multiplier in create_multipliers2():
print(multiplier(2))

方案2:修改变量i的命名空间

def create_multipliers2():
multipliers = []
for i in range(5):
def multiplier(x, i=i):
return i * x
multipliers.append(multiplier)
return multipliers

for multiplier in create_multipliers2():
print(multiplier(2))

其他推荐

https://segmentfault.com/a/1190000004461404
https://segmentfault.com/a/1190000004519811

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值