Python之函数进阶-nonlocal和LEGB

Python之函数进阶-nonlocal和LEGB

nonlocal语句

  • nonlocal:将变量标记为不在本地作用域定义,而是在上级的某一级局部作用域中定义,但不能是全局作用域中定义。

函数的销毁

  • 定义一个函数就是生成一个函数对象,函数名指向的就是函数对象。
  • 可以使用del语句删除函数,使其引用计数减1。
  • 可以使用同名标识符覆盖原有定义,本质上也是使其引用计数减1。
  • Python程序结束时,所有对象销毁。
  • 函数也是对象,也不例外,是否销毁,还是看引用计数是否减为0。

变量名解析原则LEGB

  • Local,本地作用域、局部作用域的local命名空间。函数调用时创建,调用结束消亡
  • Enclosing,Python2.2时引入了嵌套函数,实现了闭包,这个就是嵌套函数的外部函数的命名空间
  • Global,全局作用域,即一个模块的命名空间。模块被import时创建,解释器退出时消亡
  • Build-in,内置模块的命名空间,生命周期从python解释器启动时创建到解释器退出时消亡。例如 print(open),print和open都是内置的变量

图一:LEGB

Python之函数进阶-nonlocal和LEGB_第1张图片


def inc():
    c = 0
    def inner():
        c += 1
        return c
    return inner

f = inc()
print(1, f())
print(2, f())

# 报错原因,inner中c += 操作是inner函数中的c,因为没有定义inner中的c变量,所以不能用。
# 报错内容:UnboundLocalError: cannot access local variable 'c' where it is not associated with a value
def inc():
    c = 0 # 自由变量,局部变量
    def inner():
        global c
        c += 1
        return c
    return inner

f = inc()
print(1, f())
print(2, f())

# 报错原因:inner定义了global c,但是python全局中没有c变量
# 报错内容:NameError: name 'c' is not defined
def inc():
    global c
    c = 0 # 自由变量,局部变量
    def inner():
        global c
        c += 1
        return c
    return inner

f = inc()
print(1, f())
print(2, f())

# inc中和inner中都必须定义global才能使用
# 返回结果:1 1
# 返回结果:2 2
c

# 返回结果:2
del c

# 删除变量c
def inc():
    c = 0 # 自由变量,局部变量
    def inner():
        nonlocal c # nonlocal c表示不是inner的c,那就是inc的c 
        c += 1     # 闭包在c += 1这里,因为这个c不是inner的是它上一层inc的c,所以需要闭包
        return c
    return inner

f = inc()
print(1, f())
print(2, f())

# 返回结果:1 1
# 返回结果:2 2
def a():
    nonlocal c
    c = 100
print(a())

# 报错原因:nonlocal c不是本函数的c,只能向上一层函数找,但是在上一层就是global了,nonlocal不允许在global中使用。
# 报错内容:SyntaxError: no binding for nonlocal 'c' found
def inc():
    a = 1000 
    c = 0
    def inner():
        nonlocal c
        c += 1
        return c
    return inner

f = inc()
print(1, f())
print(2, f())

# 此代码主要说明,a没有闭包,因为在嵌套函数inner中没有使用到a
def inc():
    a = 1000 
    c = 0
    def inner():
        nonlocal c
        c += 1
        return c
    def t():
        nonlocal a
        print(a)
    print(t.__closure__)
    return inner
    return t

f = inc()
print(1, f())
print(2, f())

# 此代码中,a和c都用到了闭包,因为函数inner用了c,函数t用了a
c = 0
def a():
    c = 1
    def b():
        c = 2
        def c():
            c = 3
            print(c)
            
# 闭包遵循就近原则,此代码为例,如函数c的c变量注释掉,打印的c就是函数中的c,以此类推。

你可能感兴趣的:(Python,python,开发语言)