1. 程式人生 > >Python Global和Nonlocal的用法

Python Global和Nonlocal的用法

nonlocalglobal 也很容易混淆。簡單記錄下自己的理解。

解釋

global

總之一句話,作用域是全域性的,就是會修改這個變數對應地址的值。

global 語句是一個宣告,它適用於整個當前程式碼塊。 這意味著列出的識別符號將被解釋為全域性變數。 儘管自由變數可能指的是全域性變數而不被宣告為全域性變數。

global語句中列出的名稱不得用於該全域性語句之前的文字程式碼塊中。

global語句中列出的名稱不能定義為形式引數,也不能在 for 迴圈控制目標、class定義、函式定義、import語句或變數註釋中定義。

當前的實現並不強制執行這些限制,但是程式不應該濫用這種自由,因為未來的實現可能會強制執行這些限制,或者悄悄地改變程式的含義。

程式設計師注意: global是指向解析器的指令。 它僅適用於與全域性語句同時解析的程式碼。 特別是,包含在提供給內建 exec()函式的字串或程式碼物件中的全域性語句不會影響包含函式呼叫的程式碼塊,而且這種字串中包含的程式碼不會受包含函式呼叫的程式碼中的全域性語句的影響。 eval()compile()函式也是如此。

nonlocal

只在閉包裡面生效,作用域就是閉包裡面的,外函式和內函式都影響,但是閉包外面不影響。

nonlocal 語句使列出的識別符號引用除global變數外最近的封閉範圍中的以前繫結的變數。 這很重要,因為繫結的預設行為是首先搜尋本地名稱空間。 該語句允許封裝的程式碼將變數重新繫結到除全域性(模組)作用域之外的本地作用域之外。

nonlocal語句中列出的名稱與global語句中列出的名稱不同,它們必須引用封閉範圍中已經存在的繫結(無法明確確定應在其中建立新繫結的範圍)。

舉例

沒有用 nonlocalglobal

x = 0
def outer():
    x = 1
    def inner():
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 0

nonlocal 的作用範圍

x = 0
def outer():
    x = 1
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 2
# global: 0

global 的作用範圍

x = 0
def outer():
    x = 1
    def inner():
        global x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 2

注意

  • 本地的變數宣告為global,就不能在再宣告為nonlocal
x = 0
def outer():
    global x
    x = 1
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)
    inner()
    print("outer:", x)
outer()
print("global:", x)

# SyntaxError: no binding for nonlocal 'x' found

  • 使用nonlocal之前需要初始化變數
x = 0
def outer():
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)
    inner()
    print("outer:", x)
outer()
print("global:", x)
# SyntaxError: no binding for nonlocal 'x' found

  • 不能在函式的外部函式裡面宣告nonlocal
x = 0
def outer():
    x = 1
    nonlocal x
    def inner():
        x = 2
        print("inner:", x)
    inner()
    print("outer:", x)
outer()
print("global:", x)
# SyntaxError: name 'x' is assigned to before nonlocal declaration

如果你感興趣可以關注公眾號「chasays」- 程式設計師匯聚地