python闭包两种写法_python 闭包,可变参数

导论

首先,回顾下闭包的概念:返回函数

注意到,

for i in range(10):

def callback():

print "clicked button", i

UI.Button("button %s" % i, callback)

only to find that all callbacks print the same value (most likely 9, in this case). The reason for this is that Python’s nested scopes bind to variables, not object values, so all callback instances will see the current (=last) value of the “i” variable. To fix this, use explicit binding:

有两种思路来解决:绑定默认参数,构建闭包。

绑定默认参数

for i in range(10):

def callback(i=i):

print "clicked button", i

UI.Button("button %s" % i, callback)

通过绑定默认参数,把指向外部环境的动态变量(随着for循环进行一直在变化)固定住,类似于"take a snapshot"。

接下来,如果需要向callback传递别的参数怎么办?

方案:

for i in range(10):

def callback(my_str, i=i):

print my_str, i

UI.Button("button %s" % i, callback)

闭包

for i in range(10):

def closure()

def callback():

print "clicked button", i

return callback

UI.Button("button %s" % i, closure())

这里,因为closure()函数在返回另一个函数callback时,需要将运行callback()所需的local variables都封装好,形成一个闭包,所以i的值被固定下来作为闭包的一部分一起返回。

应用

给定一个字典

character_start = {'examples': '例',

'syns': '近',

'ants': '反',

'der': '派'}

希望通过一个循环,把字典里的value由str转变为匹配指定字符串行首字符是不是该str的函数。

比如,希望examples里存放的是一个判断行首字符是否为例的函数。该函数接受一个字符串作为输入,根据判断结果返回True或者False。

不正确的实现方式:

incorrect_implement_character_start = {key: lambda s: s[0] == value.decode('utf-8') for key, value in character_start.iteritems()}

# pitfall: value is a global variable and is dynamically changing,

# so finally all lambda's will refer to the last value, in this case it is the value of syns!

闭包 实现

for key, value in character_start.iteritems():

def gen_match_fun_closure(_value):

return lambda s: s[0] == _value.decode('utf-8')

character_start[key] = gen_match_fun_closure(value)

绑定默认参数 实现

corrent_implement_character_start = {key: lambda (s, _value=value): s[0] == _value.decode('utf-8') for key, value in character_start.iteritems()}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值