Python中闭包与lambda的作用域

Python中闭包与lambda的作用域

lambda写法

def fun():
    for i in range(3):
        yield lambda x : x * i

f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

闭包的写法

def fun():
    result = []
    for i in range(3):
        def demo(x):
            return x * i
        result.append(demo)
    return result
f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

上面两种写法的结果都是2,4,6,按最初的想法结果应该是0,2,6。

问题原因:
问题的本事在python的变量查找规则,LEGB(local,enclousing,global,bulitin),上面的例子中,i就是在闭包作用域(enclousing),而Python的闭包是迟绑定闭包中用到的变量i的值,是在内部函数被调用时查找到的。

解决办法
将闭包作用域变为局部作用域
lambda写法

def fun():
    for i in range(3):
        yield lambda x, i = i: x * i

f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

闭包写法

def fun():
    result = []
    for i in range(3):
        def demo(x, i=i):
            return x * i
        result.append(demo)
    return result
f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

以上输出结果0,2,6

另一种情况:

def fun():
    for i in range(3):
        yield lambda x : x * i
f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

输出结果还是2,4,6
问题原因
fun()方法返回的生成器(或迭代器),并没有真正的执行,而是在每次调用的时候进行执行。
在遍历后执行打印时,i这个变量使用的是最后调用的值。将lambda看作闭包方法的话,变量i值还是闭包作用域(no local)

猜你喜欢

转载自blog.csdn.net/qq_1290259791/article/details/80895715