您的位置:

Python Nonlocal:函数中外部变量的访问和修改

一、什么是Python Nonlocal?

在Python中,函数可以嵌套定义。在内部函数中,可以访问外部函数定义的变量。但是,在函数内部修改外部函数定义的变量是不允许的,即使您使用赋值运算符为变量赋值,Python也会创建一个新的局部变量,并且不会修改外部变量。这是出于Python语言的“cevice区分原则”和“非本地绑定原则”的考虑。

Python Nonlocal关键字解决了这个问题。当您要在内部函数中修改外部函数定义的变量时,可以使用nonlocal关键字将外部变量声明为非本地变量,并且在函数内部对其进行修改。这样,Python就可以知道您要修改的是外部变量,而不是创建一个新的局部变量。


def outer():
    x = "local"
    
    def inner():
        nonlocal x
        x = "nonlocal"
        print("inner:", x)
        
    inner()
    print("outer:", x)

outer()

在上面的例子中,我们定义了一个外部函数outer并在内部函数inner中对x变量进行修改。我们使用nonlocal关键字在函数inner中声明x变量是一个非本地变量,然后在函数体内部修改x变量的值为"nonlocal"。最后,我们在函数outer中打印x的值。 运行这段代码,您会发现x变量的值被修改为非本地值"nonlocal"。

二、Python Nonlocal 原则

在使用Python Nonlocal之前,有必要了解Python语言的“cevice区分原则”和“非本地绑定原则”。

“cevice区分原则”意味着语言不允许使用在不同cevice作用域中的同名变量相互干扰。这个原则是为了避免变量歧义和混淆。

“非本地绑定原则”表示函数内部的变量对外部变量是完全透明的。因此,函数内部的变量不能直接修改或访问外部变量。

然而,Python Nonlocal使得函数内部的函数能够访问和修改外部变量。这使得函数的设计更加灵活。但是,Python Nonlocal并不是用于每个函数中的,仅限于需要在函数内访问外部变量的情况。

三、Python Nonlocal 和 Global 关键字的对比

除了Python Nonlocal,Python还提供了一个global关键字来访问和修改全局变量。这两个关键字非常相似,它们都允许内部函数访问并修改外部变量。然而,它们也有着重要的区别。

global关键字用于在函数内部声明全局变量,而nonlocal关键字用于在函数内部声明外部变量,因此nonlocal关键字只允许访问在函数外部定义的变量而非全局变量。同时,使用nonlocal的函数仅对非本地变量进行修改,而全局变量可以被访问和修改。

在实践中,如果您需要在一个函数中访问全局变量,并在该函数中修改该变量,则应使用global关键字。 如果一个变量需要在函数嵌套中共享,而不是在函数之间共享,则应该使用nonlocal关键字。

四、Python Nonlocal的使用场景

使用Python Nonlocal有几种使用场景,例如:

1.当您需要在嵌套的函数中访问并修改外部变量时。

2.当您需要在许多地方使用同一个变量时,但不希望将其转换为全局变量时。

3. 通过在函数之间共享变量,您可以编写更简洁,更优雅的代码


def counter():
    count = 0
  
    def func1():
        nonlocal count
        count += 1
        return count
  
    def func2():
        nonlocal count
        count += 1
        return count
      
    return func1, func2
  
c1, c2 = counter()
print(c1())
# Output: 1
print(c2())
# Output: 2
print(c1())
# Output: 3

在上面的例子中,我们定义了一个计数器函数,它返回两个内部函数func1和func2,每次调用一个内部函数时,变量count的值加1。我们使用nonlocal关键字以方便地访问并修改变量count。最后,我们调用内部函数c1和c2,每次调用一个函数时,count的值都会增加。

五、结论

在Python中,nonlocal关键字允许内部函数访问并修改外部变量。它只对嵌套函数内部使用,如果您需要全局访问变量,则需要使用global关键字。使用Python Nonlocal可以编写更优雅,简洁,可读性更好的代码。它提供了更多的选项来创建可维护和可扩展的代码。