欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python 闭包

程序员文章站 2022-04-24 16:29:50
python 闭包 1.什么是闭包 如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用, 那么[内部函数和该变量]就构成了闭包(closure)。 inner 和 x构成一个闭包 2.闭包使用中的坑 闭包中不能直接修改外部函数的局部变量 (如果使用类似 修改x的值,会直接报错 ......

# python 闭包 #

1.什么是闭包

如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,
那么[内部函数和该变量]就构成了闭包(closure)。

def out(x):
    def inner():
        print(x)
    return inner

inner 和 x构成一个闭包

2.闭包使用中的坑

闭包中不能直接修改外部函数的局部变量

(如果使用类似x = x + 1修改x的值,会直接报错UnboundLocalError
原因是企图修改x会让函数认为x是局部变量,在执行=右边的x + 1时找不到变量x)

def out():
    x = 0
    def inner():
        x = 1
        print(x)
    print(x)  # 显示改变前变量的值
    inner()  # 执行inner函数
    print(x)  # 显示改变后的变量值
    return inner

输出0 1 0

如果非要修改外部函数局部变量的值

需要使用nonlocal

def out():
    x = 0
    def inner():
        nonlocal x
        x = 1
        print(x)
    print(x)  # 显示改变前变量的值
    inner()  # 执行inner函数
    print(x)  # 显示改变后的变量值
    return inner

输出0 1 1

当闭包中引用了循环变量时

def out():
    fs = []
    for i in range(1, 4):
        i = i

        def inner(x):
            return i + x

        fs.append(inner)
    return fs


f1, f2, f3 = out()
print(f1(1))
print(f2(1))
print(f3(1))

输出4 4 4而不是2 3 4
闭包中的函数在被调用时才执行,
当调用inner时外层函数out已经执行完了,
但是变量i不会销毁,因为函数inner需要使用变量i,
而此时变量i的值为3,所以输出4 4 4
想要获得2 3 4,需要在每一次循环时都记录变量i的值

def out():
    fs = []
    for i in range(1, 4):
        i = i

        def inner(x, y=i):
            return x + y

        fs.append(inner)
    return fs


f1, f2, f3 = out()
print(f1(1))
print(f2(1))
print(f3(1))

输出2 3 4