本地與全域性範圍

什麼是本地和全域性範圍?

在程式碼中的某些位置可訪問的所有 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!