python 闭包

一、定义

定义:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)

说人话:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)

>>>def addx(x):  
>>>    def adder(y): return x + y  
>>>    return adder  
>>> c =  addx(8)  
>>> type(c)  
  
>>> c.__name__  
'adder'  
>>> c(10)

结合这段简单的代码和定义来说明闭包:
如果在一个内部函数里:adder(y)就是这个内部函数,
对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域addx里面,但不在全局作用域里,
则这个内部函数adder就是一个闭包。

再稍微讲究一点的解释是,闭包=函数块+定义函数时的环境,adder就是函数块,x就是环境,当然这个环境可以有很多,不止一个简单的x。

二、使用闭包注意事项

1.闭包中是不能修改外部作用域的局部变量的


def f1():
    m=1
    def f2():
        m=0
        print(m)
    print(m)
    f2()
    print(m)
f1()

#1
#0
#1
#[Finished in 0.1s]

2.使用闭包时一段经典的错误代码

ef foo():
    a=1
    def add():
        nonlocal a #这句注释掉就会出错
        a = a+1
        return a
    return add()

    
c=foo()
print(c)
#2

这段程序的本意是要通过在每次调用闭包函数时都对变量a进行递增的操作,但在实际使用时:因为在执行代码 c = foo()时,python会导入全部的闭包函数体add()来分析其的局部变量,python规则指定所有在赋值语句左面的变量都是局部变量,则在闭包add()中,变量a在赋值符号"="的左面,被python认为是add()中的局部变量。再接下来执行print (c)时,程序运行至a = a + 1时,因为先前已经把a归为add()中的局部变量,所以python会在add()中去找在赋值语句右面的a的值,结果找不到,就会报错。

解决的方法很简单:
使用语句nonloacal a就可以了,该语句显式的指定a不是闭包的局部变量。

参考博客:https://www.cnblogs.com/JohnABC/p/4076855.html

你可能感兴趣的:(python 闭包)