本地与全局范围

什么是本地和全局范围?

在代码中的某些位置可访问的所有 Python 变量都在本地范围全局范围内

解释是局部范围包括当前函数中定义的所有变量,全局范围包括在当前函数外部定义的变量。

foo = 1  # global

def func():
    bar = 2  # local
    print(foo)  # prints variable foo from global scope
    print(bar)  # prints variable bar from local scope

可以检查哪个变量在哪个范围内。内置函数 locals()globals() 将整个范围作为字典返回。

foo = 1

def func():
    bar = 2
    print(globals().keys())  # prints all variable names in global scope
    print(locals().keys())  # prints all variable names in local scope

姓名冲突会发生什么?

foo = 1

def func():
    foo = 2  # creates a new variable foo in local scope, global foo is not affected

    print(foo)  # prints 2

    # global variable foo still exists, unchanged:
    print(globals()['foo'])  # prints 1
    print(locals()['foo'])  # prints 2

要修改全局变量,请使用关键字 global

foo = 1

def func():
    global foo
    foo = 2  # this modifies the global foo, rather than creating a local variable

范围是为整个功能定义的!

这意味着一个变量永远不会是函数的一半和局部的全局变量,反之亦然。

foo = 1

def func():
    # This function has a local variable foo, because it is defined down below.
    # So, foo is local from this point. Global foo is hidden.

    print(foo) # raises UnboundLocalError, because local foo is not yet initialized
    foo = 7
    print(foo)

同样,对面:

foo = 1

def func():
    # In this function, foo is a global variable from the begining

    foo = 7  # global foo is modified

    print(foo)  # 7
    print(globals()['foo'])  # 7

    global foo  # this could be anywhere within the function
    print(foo)  # 7

功能内的功能

函数中可能存在许多级别的函数,但在任何一个函数中,该函数和全局范围只有一个本地范围。没有中间范围。

foo = 1

def f1():
    bar = 1

    def f2():
        baz = 2
        # here, foo is a global variable, baz is a local variable
        # bar is not in either scope
        print(locals().keys())  # ['baz']
        print('bar' in locals())  # False
        print('bar' in globals())  # False

    def f3():
        baz = 3
        print(bar)  # bar from f1 is referenced so it enters local scope of f3 (closure)
        print(locals().keys())  # ['bar', 'baz']
        print('bar' in locals())  # True
        print('bar' in globals())  # False

    def f4():
        bar = 4  # a new local bar which hides bar from local scope of f1
        baz = 4
        print(bar)
        print(locals().keys())  # ['bar', 'baz']
        print('bar' in locals())  # True
        print('bar' in globals())  # False

global vs nonlocal(仅限 Python 3)

这两个关键字都用于获取对当前函数不是本地变量的写访问权。

global 关键字声明应将名称视为全局变量。

foo = 0  # global foo

def f1():
    foo = 1  # a new foo local in f1
    
    def f2():
        foo = 2  # a new foo local in f2
        
        def f3():
            foo = 3  # a new foo local in f3
            print(foo)  # 3
            foo = 30  # modifies local foo in f3 only
        
        def f4():
            global foo
            print(foo)  # 0
            foo = 100  # modifies global foo

另一方面,Python 3 中提供的 nonlocal(参见非局部变量 )将一个局部变量从一个封闭的范围带入当前函数的局部范围。

nonlocalPython 文档

非本地语句使列出的标识符引用最近的封闭范围中除了全局变量之前绑定的变量。

Python 3.x >= 3.0
def f1():
    
    def f2():
        foo = 2  # a new foo local in f2

        def f3():
            nonlocal foo  # foo from f2, which is the nearest enclosing scope
            print(foo)  # 2
            foo = 20  # modifies foo from f2!