py3 nonlocal及函数嵌套调用

Python里只有2种作用域:

全局作用域:全局作用域是指当前代码所在模块的作用域

局部作用域:局部作用域是指当前函数或方法所在的作用域

局部作用域里的代码可以读外部作用域(包括全局作用域)里的变量,但不能更改它。一旦进行更改,就会将其当成是局部变量。而如果在更改前又进行了读取操作,则会抛出异常。

 

而在解决作用域问题有两个关键字:globalnonlocal

其中,nonlocal是python3.X才引入的

 

在Python 2.x中,闭包只能读外部函数的变量,而不能改写它。

所以如果要更改外部作用域里的变量,最简单的办法就是将其放入全局作用域,用global关键字引入该变量。

当然这也是py3可以实现的最简单操作。其需要在每个函数中先用global声明,否则会报错

a = 100
def aa():
    a += 1
    print(a)
aa()

#运算结果如下
Traceback (most recent call last):
  File "...", line ..., in 
    aa()
  File "...", line ..., in aa
    a += 1
UnboundLocalError: local variable 'a' referenced before assignment

Process finished with exit code 1

只需要加上一行,用global声明一下全局变量a,即可在函数中修改a的值,如下:

a = 100
def aa():
    global a
    a += 1
    print(a)
aa()
print(a)

#运行结果
101
101

Process finished with exit code 0

这里和c语言不同,在开始定义a的时候无需声明为全局变量,而是在函数中说明

那么nonlocal是怎么使用呢

a = 100
def aa():
    b = 200
    def bb():
        b += 2
        return b
    bb()
aa()

#运行结果
Traceback (most recent call last):
  File "...y", line ..., in 
    aa()
  File "...", line ..., in aa
    bb()
  File "...", line ..., in bb
    b += 2
UnboundLocalError: local variable 'b' referenced before assignment

Process finished with exit code 1

b未被赋值,这种情况下我们可以在多层次的函数嵌套中使用nonlocal:

a = 100
def aa():
    b = 200
    def bb():
        nonlocal b
        b += 2
        return b
    print(b)
    bb()
    print(b)
aa()
#print(b)

#运行结果
200
202

Process finished with exit code 0

注:最后的print(b)依然会报错,因为b是局部变量,仅存在于函数aa()中

而在单层的函数中,nonlocal并不适用:

a = 100
def aa():
    nonlocal a
    a += 11
    return a
print(a)
aa()
print(a)

#运行结果
  File "...", line ...
    nonlocal a
    ^
SyntaxError: no binding for nonlocal 'a' found

Process finished with exit code 1

嵌套函数的几种使用:

#程序1
def a():
    x = 0
    def b():
        nonlocal x
        x += 1
        print(x)
    return b
    #b()    这里有和没有效果一样
a()()

#程序1运行结果
1

Process finished with exit code 0

#程序2
def a():
    x = 0
    def b():
        nonlocal x
        x += 1
        print(x)
    #return b
    b()    #同样有和没有效果一样
a()()

#程序2运行结果
1
Traceback (most recent call last):
  File "...", line ..., in 
    a()()
TypeError: 'NoneType' object is not callable

Process finished with exit code 1

#程序3
def a():
    x = 0
    def b():
        nonlocal x
        x += 1
        print(x)
    return b    #这个有和没有效果一样
    #b()
a()

#程序3运行结果

Process finished with exit code 0

#程序4
def a():
    x = 0
    def b():
        nonlocal x
        x += 1
        print(x)
    return b
    b()
a()

#程序4运行结果

Process finished with exit code 0

#若将return注释掉,则运行结果
1

Process finished with exit code 0

嵌套两个:

def a():
    x = 0
    def b():
        nonlocal x
        x += 1
        print(x)
    #return b()
    b()
    def c():
        nonlocal x
        x += 3
        print(x)
    #return c()
    c()
a()

#运行结果
1
4

Process finished with exit code 0

 

 

你可能感兴趣的:(Python)