考虑以下代码
func_list = []def foo(d): print 'num', num _num = num return d['level'] > _numdef get_f(num): _num = num def bar(d): print 'num', _num return d['level'] > _num return barfor num in (30, 60): level_func = foo #level_func = get_f(num) func_list.append(level_func)d = {'level': 40}for f in func_list: print f(d)
当level_func是foo时,两次调用都会输出num=60,而level_func = get_f(num),才会输出期望的num=30, num=60。
原因是循环中level_func都绑定了同一个local变量num,而循环结束后,变量num的值为60,所以输出都是60。而get_f里面定义了_num=num,bar函数的_num是指向get_f里面所定义的_num,这是因为Python里def定义函数创造了一个新的variable scope;循环两次,get_f里形成闭包,保存了循环当时的值。
但每次都要定义一个辅助函数(上例的get_f)总觉得麻烦,如何解决?其实可以利用Python的一个“坑”。代码:
level_func = lambda d, num=num: return d['level'] > num
原理就是利用Python函数默认参数是在定义时绑定。
具体的差别可以用过dis模块来打印函数的bytecode查看。
原文地址:Python循环中的local变量绑定问题, 感谢原作者分享。 一直觉得人应该去旅行,在年轻的时候,