python函数作用域,嵌套函数,闭包

函数作用域                                                                                                                                                                   

 命名空间:

从python解释器开始执行之后,就在内存中开辟了一个空间,每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来。但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心。等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量会存储在新开辟出来的内存中。函数中的变量只能在函数的内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。我们给这个“存放名字与值的关系”的空间起了一个名字——叫做命名空间

代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间,在函数的运行中开辟的临时的空间叫做局部命名空间

命名空间的本质: 存放变量名和值的绑定关系。

命名空间种类:全局名名空间,局部命名空间,内置命明空间

* 内置明明空间中保存的python内置方法的绑定关系。

命名空间的取值顺序 : 局部命明空间----全局命名空间------内置命名空间

作用域:

作用域时按范围分的,分为全局作用域和局部作用域,全局作用域中的变量叫全局变量,局部作用域中的叫局部变量。

全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

局部作用域:局部名称空间,只能在局部范围内生效

查看全局变量和局部变量的方法分别是globals 和 locals。

在局部如果可以直接引用全局变量,如果想要修改就需要用到 global 关键字
name = "Alex"      # 定义一个全局变量name
def user():
    global name     # 引用全局变量name
    name = "alex"   # 给全局变量name重新赋值
    print(name)
 
    
user()
print(name)         # 这里打印出来的就是更改后的name

函数嵌套:

在函数的内部又声明了另一个函数,就叫函数的嵌套。

def f1():
    a = 5
    print(a)      # 函数f1定义了一个变量a,所以会从自己内部找a的值
    
    def f2():
        print(a)  # 函数f2并未定义变量a,所以回去上一级f1中去找变量a的值
        
        def f3():
            a = 6
            print(a)    # 函数f3中定义了变量a,所以会输出自身中定义的a的值,函数内部的变量是独立的,所以并不会改变上级函数中a的值
    
        f3()
    f2()
    
    
f1()

如果想要改变外部函数的中的变量a的值,需要用到关键字 nonlocal
1.外部必须有这个变量
2.在内部函数声明nonlocal变量之前不能再出现同名变量
3.内部修改这个变量如果想在外部有这个变量的第一层函数中生效
def f1():
    a = 3
    def f2():
        nonlocal a
        a = 2
    f2()
    print(a)
f1()

闭包:

当一个内部函数引用了他外部函数中的变量,并在外部函数中被调用时就会形成闭包。
一般我们这样使用闭包:

def ouder():
    name = "Alex"
    
    def inner():
        print(name)
    return inner   # 这里时ouder函数的返回值


f = ouder()    # f拿到的时ouder函数的返回值inner
f()             # 这里f()就相当于inner()

判断闭包的方法 __closure__ , 根据打印的结果中是否以cell元素开头判定函数是不是闭包。
def ouder():
    name = "Alex"
    
    def inner():
        print(name)
    print(inner.__closure__)
    
    return inner  # 这里时ouder函数的返回值


f = ouder()  # f拿到的时ouder函数的返回值inner
f()  # 这里f()就相当于inner()




猜你喜欢

转载自www.cnblogs.com/zt0903/p/10683606.html