变量起作用的代码范围称为变量的作用域,不同作用域内同名变量之间互不影响。在函数外部和函数内部定义的变量,其作用域是不同的,函数内部定义的变量一般为局部变量,在函数外部定义的变量为全局变量。不管是局部变量还是全局变量,其作用域都是从定义的位置开始的,在此之前无法访问。
在函数内定义的局部变量只在该函数内可见,当函数运行结束以后,在其内部定义的所有局部变量将被自动删除而不可访问。在函数内部使用 global 定义的局部变量当函数结束后仍然存在并且可以访问。
如果在函数内部修改一个定义在函数外的变量值,必须使用 global 明确声明,否则会自动创建新的局部变量。在函数内部通过 global 关键字来声明或定义全局变量,这分两种情况。
(1) 一个变量已在函数外定义,如果在函数内需要修改这个变量的值,并将修改的结果反映到函数之外,可以在函数内用关键字 global 明确声明要使用已定义的同名全局变量。
(2)在函数内部直接使用 global 关键字将一个变量声明为全局变量,如果在函数外没有定义该全局变量,在调用这个函数后,会创建新的全局变量。
① 在函数内如果只引用某个变量的值而没有为其赋新值,该变量为(隐式的)全局变量。
② 如果在函数内某条代码有为变量赋值的操作,该变量就被认为是(隐式的)局部变量,除非在函数内赋值操作之前显示地用关键字 global 进行了声明。
def func():
global x # 声明或创建全局变量,必须在使用 x 之前执行
x = 3 # 修改全局变量的值
y = 4 # 局部变量
print(x, y)
x = 5 # 在函数外部定义了全局变量x
func()
print(x)
# print(y) # 局部变量在函数运行结束之后自动删除,不再存在
del x # 删除了全局变量x
# print(x) # NameError: name 'x' is not defined
func() # 本次调用创建了全局变量
print(x)
如果在某个作用域内有为变量赋值的操作,那么该变量将被认为是该作用域内的局部变量。
def func():
print(x) # 这条语句会引发异常,因为变量 x 现在还不存在
x = x + 1 # 赋值语句,x 将被认为是该作用域内的局部变量
# print(x)
# UnboundLocalError: local variable 'x' referenced before assignment
# func()
y = 10
def demo():
print(y)
demo()
如果局部变量与全局变量具有相同的名字,那么该局部变量会在自己的作用域内暂时隐藏同名的全局变量。
def func():
x = 3 # 创建了局部变量,并自动隐藏了同名的全局变量
print(x)
x = 5 # 创建了全局变量
print(x)
func()
print(x) # 函数调用结束后,不影响全局变量 x 的值