全局变量

在 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 属于某个封闭范围(函数范围,全局范围或内置函数)