如何在循环中正确设置动态定义的全局函数?解决函数指向异常
嗨,这个问题我之前也踩过坑!这是Python闭包中经典的变量延迟绑定陷阱,我来给你拆解一下:
问题根源:lambda的延迟变量引用
你的lambda函数并没有在循环迭代时就“记住”当前的magic值,而是在函数被调用的那一刻才去查找magic的当前值。等你调用MAGIC1和MAGIC2的时候,循环已经跑完了,magic最后停在了列表的最后一个元素"Magic2",所以两个函数都会用这个值输出。
怎么解决?
有两种简单靠谱的方法:
方法1:用默认参数固定当前值
利用Python函数默认参数在定义时就求值的特性,把当前的magic值作为默认参数传入lambda,这样每个lambda都会绑定迭代时的具体值:
import sys arr = ["Magic1", "Magic2"] for magic in arr: print(magic) # 添加默认参数m=magic,定义时就锁定当前的magic值 globals()[magic.upper()] = lambda x, m=magic: sys.stdout.write(x + m + '\n') MAGIC1("foo") MAGIC2("foo")
方法2:用functools.partial提前绑定参数
如果觉得lambda的默认参数写法有点绕,可以用functools.partial来明确绑定参数值,可读性更好:
import sys from functools import partial def write_with_suffix(x, suffix): sys.stdout.write(x + suffix + '\n') arr = ["Magic1", "Magic2"] for magic in arr: print(magic) # 提前把当前的magic绑定到函数的suffix参数上 globals()[magic.upper()] = partial(write_with_suffix, suffix=magic) MAGIC1("foo") MAGIC2("foo")
运行这两种写法的代码,就能得到你期望的输出:
Magic1
Magic2
fooMagic1
fooMagic2
内容的提问来源于stack exchange,提问作者merlin2011
相关产品推荐
相关产品推荐

