关于python:关于范围:全局和本地分配

Regarding Scope : Global and Local Assignment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def scope_test():
    def do_local():
        spam ="local spam"

    def do_nonlocal():
        nonlocal spam
        spam ="nonlocal spam"

    def do_global():
        global spam
        spam ="global spam"

    spam ="test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)

您好,我正在处理python类,并面对来自官方文档的上述示例。

输出:

After local assignment: test spam

After nonlocal assignment: nonlocal spam

After global assignment: nonlocal spam

In global scope: global spam

do_local之后的第一次打印的结果仍然打印"测试垃圾邮件",但不知道为什么第二次打印会显示"非本地垃圾邮件"。

有什么区别?

我的推论是,如果我做了_local(),那么它会运行do_local(),并将spam变量更改为"local spam",它可能必须与do_nonlocal()一起工作,这会导致"非本地spam"。但事实并非如此。

为什么?


下面是一个全局变量示例(从这里开始):

1
2
3
4
5
6
7
8
9
10
11
globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

正如您在本例中看到的,global表示脚本中任何位置都可用的变量。如果在函数中定义或更改全局变量,则可以在具有全局关键字的另一个函数中使用它。

甚至可以删除示例中的第一行定义:

1
globvar = 0

它作为全局变量工作。因此,当您使用全局关键字时,它在脚本的任何范围内都可用。

非本地定义

Python 3 introduced the nonlocal keyword that allows you to assign to
variables in an outer, but non-global, scope.

这意味着,当您使用非本地关键字时,它是可用的外部作用域。在这种情况下,"非本地垃圾邮件"在do_nonlocal()函数中也可以在scope_test()函数中使用,但不能再在一个外部作用域中使用。

如果不使用全局关键字和非本地关键字,那么在函数中定义"spam",它只是一个局部变量,当函数结束时,它就会被删除。

编辑

这不是相同的代码,而是打印相同的结果。为了更好地理解,情况是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
spam_1 =""

def scope_test():
    def do_local():
        spam_3 ="local spam"

    def do_nonlocal():
        nonlocal spam_2
        spam_2 ="nonlocal spam"

    def do_global():
        global spam_1
        spam_1 ="global spam"

    spam_2 ="test spam"
    do_local()
    print("After local assignment:", spam_2)
    do_nonlocal()
    print("After nonlocal assignment:", spam_2)
    do_global()
    print("After global assignment:", spam_2)

scope_test()
print("In global scope:", spam_1)