Python作用域规则(LEGB)中的一个黑色角落--------lambda表达式与def

正文

存在于函数封闭作用域内的变量(即通过Python的LEGB规则找到的变量)并且不是在函数作用域中创建的变量对于函数本身而言在效果上相当于函数的一个隐式参数(即在调用函数时没有显式传递给该函数,但函数能使用该变量)。

当一个函数中存在这种变量时,函数运行会随外界中该变量的改变而产生不同的结果,对lambda函数运行生成函数时亦是如此。

并且在lambda(或def)内部,封闭作用域内对变量的引用实际上是在生成函数被调用时决定的,而非它创建时。 而由于我们编程时函数创建和函数调用通常不是绑定在一起的,这会造成一个存在于函数编程上的问题(通常是存在于工厂函数中) ------ 这将导致使用工厂函数产生的函数结果与预想中的函数不符。
例如:

def odd():
	funcs = []
	for c in 'abcd':
		funcs.append(lambda: c)
	return funcs
#odd是一个工厂函数,调用odd函数时会产生并返回一组函数。

for func in odd():
	print(func(), end='')

#注:输出为'dddd'而非'abcd',
#要想输出'abcd'应该把“funcs.append(lambda: c)”一句改为“funcs.append(lambda c=c: c)”

而这种情况通常会被我们误解,尽管这种情况不太常见。

lambda调用在python的GUI中极为重要,通常用lambda表达式和对象引用来延迟调用,避免在标签按钮创建时就运行回调(如:Button(command=func()) )。lambda表达式或者可调用的引用服务都可以用来延迟回调的触发,直至随后事件的发生)。
这导致了以上情况可能在GUI中相对比较常见

于此提醒。

猜你喜欢

转载自blog.csdn.net/San__Qi/article/details/100567631