全域性變數

在 Python 中,當且僅當函式內部的變數出現在賦值語句的左側或其他某些繫結事件中時,它們才被視為區域性變數。否則,在封閉函式中查詢這樣的繫結,直到全域性範圍。即使從未執行賦值語句也是如此。

x = 'Hi'

def read_x():
    print(x)   # x is just referenced, therefore assumed global

read_x()       # prints Hi

def read_y():
    print(y)   # here y is just referenced, therefore assumed global

read_y()       # NameError: global name 'y' is not defined

def read_y():
    y = 'Hey'  # y appears in an assignment, therefore it's local
    print(y)   # will find the local y

read_y()       # prints Hey

def read_x_local_fail():
    if False:
        x = 'Hey'  # x appears in an assignment, therefore it's local
    print(x)   # will look for the _local_ z, which is not assigned, and will not be found

read_x_local_fail()   # UnboundLocalError: local variable 'x' referenced before assignment

通常,作用域內的賦值將遮蔽同名的任何外部變數:

x = 'Hi'

def change_local_x():
    x = 'Bye'
    print(x)
change_local_x()  # prints Bye
print(x)  # prints Hi

宣告名稱 global 意味著,對於範圍的其餘部分,名稱的任何分配都將在模組的頂層發生:

x = 'Hi'

def change_global_x():
    global x
    x = 'Bye'
    print(x)

change_global_x()  # prints Bye
print(x)  # prints Bye

global 關鍵字意味著分配將發生在模組的頂層,而不是程式的頂層。其他模組仍然需要通常的點模式訪問模組中的變數。

總結一下:為了知道變數 x 是否是函式的區域性變數,你應該讀取整個函式:

  1. 如果你找到了 global x,那麼 x 是一個全域性變數
  2. 如果你找到了 nonlocal x,那麼 x 屬於一個封閉的函式,既不是本地的也不是全域性的
  3. 如果你發現了 x = 5for x in range(3) 或其他一些繫結,那麼 x 是一個區域性變數
  4. 否則 x 屬於某個封閉範圍(函式範圍,全域性範圍或內建函式)