python中的非本地作用域(nonlocal scope in python)

我们知道python中的变量(variable)的作用域(scope)取决于该变量在源代码的何处被赋值。一般而言,变量在三种不同的位置被赋值,对应如下的三种作用域:

  • 全局作用域(global scope)
  • 本地作用域(local scope)
  • 非本地作用域(nonlocal scope)

前两种是很容易理解的:变量在函数外被赋值,作用域即为global,也就能被.py文件中的所有函数访问;变量在某个函数内被赋值,就是那个函数的本地变量,也只能在该函数内部进行访问。

第三种作用域其实是第二种作用域的特殊情况,也即nonlocal scope 是特殊的local scope。要理解nonlocal scope,首先我们应明白函数是可以嵌套定义的,比如下面这样

def outer_func():
    inner_num = 813
    def inner_func1():
        print(f"I'm func1, inner number is {inner_num}")
    return inner_func1

inner_func = outer_func()
inner_func()

上面的例子中,inner_num这个变量在outer_func内部、inner_func1的外部被定义,即,对于outer_func来说它是一个local variable,对于inner_func1来说它是一个nonlocal variable。那么函数能否访问自己的nonlocal variable呢?答案是肯定的(可以运行一下上面的代码试试)。

需要注意的是,在内嵌函数中修改非本地变量,正如在函数中访问全局变量一样,需要有一个关键字声明,前者是nonlocal,后者是global

def outer_function():
    x = 10  # 局部变量 x
    
    def inner_function():
        nonlocal x  # 声明 x 为非本地变量
        x += 5  # 修改 x 的值
        print("Inner function:", x)
    
    inner_function()
    print("Outer function:", x)

outer_function()

以上代码的结果是

Inner function: 15
Outer function: 15

如果声明nonlocal x,运行程序会出现以下报错

UnboundLocalError: local variable 'x' referenced before assignment

 即编译器认为x是内嵌函数的local variable,但这个变量在引用之前就赋值了。

因此,无论是inner function(nested function)中访问和修改nonlocal variable,最好都先用nonlocal进行声明。

你可能感兴趣的:(Python,python)