鱼C论坛

 找回密码
 立即注册
查看: 1192|回复: 0

[技术交流] 020函数:内嵌函数和闭包

[复制链接]
发表于 2018-2-19 23:19:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
020函数:内嵌函数和闭包

在Python中,当引用一个变量的时候,对这个变量的搜索是

按找本地作用域(Local)、嵌套作用域(Enclosing function

locals)、全局作用域(Global)、内置作用域(builtins模块

)的顺序来进行的,即所谓的LEGB规则。

然而当在一个函数内部为一个变量赋值时,并不是按照上面

所说LEGB规则来首先找到变量,之后为该变量赋值。在

Python中,在函数中为一个变量赋值时,有下面这样一条规

则:
“当在函数中给一个变量名赋值是(而不是在一个表达式中

对其进行引用),Python总是创建或改变本地作用域的变量

名,除非它已经在那个函数中被声明为全局变量. ”

>>>x = 99
>>>def func():
           x = 88
>>>func()
>>>print(x)
99

因为func函数中并没有变量x,因此Python会在func函数的

本地作用域创建一个变量x,也就是说此x并非x = 99中的x

>>>x = 99
>>>def func():
           global x
           x = 88
>>>func()
>>>print(x)
88

上述程序中的global x语句告诉Python在func的本地作用

域内,要使用全局作用域中的变量x,因此在下面的x = 88

语句中,Python不会再在本地作用域中新建一个变量,而是

直接引用全局作用域中的变量x

nonlocal关键字可以在一个嵌套的函数中修改嵌套作用域中

的变量

>>>def func():
           count =1
           def foo():
                   count = 12
           foo()
           print(count)
>>>func()
1

上面的程序中,在嵌套的foo函数中,对变量count赋值,同

样会创建一个新的变量,而非使用count = 1语句中的count

>>>def func():
           count =1
           def foo():
                   nonlocal count
                   count = 12
           foo()
           print(count)
>>>func()
12

上面的程序中,在foo函数中使用了nonlocal关键字,就会

告诉Python在foo函数中使用嵌套作用域中的变量count,因

此对变量count进行修改时,会直接影响到嵌套作用域中的

count变量,程序最后也就输出12了

注意:使用global关键字修饰的变量之前可以并不存在,而

使用nonlocal关键字修饰的变量在嵌套作用域中必须已经存

在。


作用域:一个标识符的可见范围,就是标识符的作用域。一

般常说的变量的作用域。

全局作用域(global):在整个程序运行环境中都可见。
局部作用域:在函数、类等内部可见;局部变量使用范围不

能超过其所在的局部作用域

global使用原则:外部作用域变量会内部作用域可见,但也

不要在这个内部的局部作用域中直接使用,因为函数的目的

是为了封装,尽量与外界隔离。如果函数需要使用外部全局

变量,请使用函数的形参传参解决。一句话:不用global,

学习它就是为了深入理解变量作用域。

闭包:

  在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。

一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。


#闭包函数的实例
# outer是外部函数 a和b都是外函数的临时变量
def outer( a ):
    b = 10
    # inner是内函数
    def inner():
        #在内函数中 用到了外函数的临时变量
        print(a+b)
    # 外函数的返回值是内函数的引用
    return inner

if __name__ == '__main__':
    # 在这里我们调用外函数传入参数5
    #此时外函数两个临时变量 a是5 b是10 ,并创建了内函数,然后把内函数的引用返回存给了demo
    # 外函数结束的时候发现内部函数将会用到自己的临时变量,这两个临时变量就不会释放,会绑定给这个内部函数
    demo = outer(5)
    # 我们调用内部函数,看一看内部函数是不是能使用外部函数的临时变量
    # demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数
    demo() # 15

    demo2 = outer(7)
    demo2()#17

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 07:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表