非局部变量和全局变量有什么区别?

18

我正在学习编程语言的概念。

在 Python 语法中,我发现了“nonlocal”这个术语。

那么,在 Python 中,“nonlocal”是什么意思呢?


请见 https://www.smallsurething.com/a-quick-guide-to-nonlocal-in-python-3/ - boardrider
这个回答解决了你的问题吗?Python nonlocal语句/关键字 - Karl Knechtel
5个回答

23

在嵌套块中存在非局部变量。使用关键字nonlocal,并获取最近的封闭块中的值。例如:

非局部变量存在于嵌套块中。使用关键字 nonlocal 并取自最近的封闭块的值。例如:

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

由于内部函数改变了 x 的值,所以输出两次均为“nonlocal”。


1
你是不是想说“块”或“作用域”,而不是“循环”?这个例子中没有循环。 - user118967

15
"nonlocal" 意味着一个变量既不是“局部的”也不是“全局的”,即该变量来自封闭的命名空间(通常是嵌套函数的外部函数)。
非局部变量和全局变量之间的一个重要区别是,非局部变量必须已经在封闭的命名空间中绑定(否则将引发语法错误),而在局部作用域中进行全局声明不需要预先绑定变量(如果变量未预先绑定,则会在全局命名空间中创建一个新的绑定)。

10

inner() 中的 nonlocal foo 可以访问 middle() 中的非本地变量 foo = 10,但无法访问 outer() 中的非本地变量 foo = 5 或者在 outer() 外部的全局变量 foo = 0,如下所示:

foo = 0 # <- ✖
def outer():
    foo = 5 # <- ✖
    def middle():
        foo = 10 # <- 〇
        def inner():
            nonlocal foo # Here
            foo += 1
            print(foo) # 11
        inner()
    middle()
outer()

inner() 中的 global foo 可以访问 全局变量 foo = 0,但无法访问 outer()middle() 中的 非局部变量 foo = 5,如下所示:

foo = 0 # <- 〇
def outer():
    foo = 5 # <- ✖
    def middle():
        foo = 10 # <- ✖
        def inner():
            global foo # Here
            foo += 1
            print(foo) # 1
        inner()
    middle()
outer()

6
从关于nonlocal语句的文档中可以了解到:
非局部(nonlocal)语句会导致所列出的标识符引用最近封闭作用域中先前绑定的变量。这很重要,因为绑定的默认行为是首先搜索本地命名空间。该语句允许封装的代码重新绑定除全局(模块)作用域之外的局部作用域外的变量。
与global语句中列出的名称不同,nonlocal语句中列出的名称必须引用封闭作用域中的现有绑定(应该创建新绑定的作用域无法明确确定)。
nonlocal语句中列出的名称不能与局部作用域中的现有绑定发生冲突。

0
global x

def outer():

    x="global"

    def inner():
        nonlocal x
        x="nonlocal"

    def inner2():
        x="local"

inner2()

print(x)

inner()

print(x)

outer()


Output:

global

nonlocal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接