变量作用域variables scope(或 命名空间namespace)是编程语言中一个非常基本的概念。每个开发人员,无论使用哪种语言,都知道局部变量local variables和全局变量global variables的定义。然而,在 Python 中,情况变得有些复杂。以下问题在 Python 开发人员的面试中出现过很多次:
nonlocal
关键字?本篇文章将由浅入深地讲解 Python 的作用域scope。阅读后,您将完全掌握这一重要概念。
LEGB 规则定义了 Python 解释器interpreter检索变量名的顺序。这四个字母代表 Python 中的四种变量variables类型:
在程序中调用命名变量时,将在本地local、封闭enclosing、全局global和内置built-in作用域中scope依次检索对应的变量。如果命名变量存在,那么将使用第一个出现的变量。否则,将引发错误 raise error。
让我们来看一个例子:
name = "Zhang"
def print_name():
name = "Python Guru"
print(name)
print_name() # Python Guru
print(name) # Zhang
如上例所示,函数function print_name()
调用了局部变量local variable name
。函数function print()
调用了全局变量global variable name
。
如果我们要修改函数function中的全局变量global variable name
,则需要使用 global
关键字keyword的语句statement。
name = "Zhang"
def print_name():
global name
name = "Python Guru"
print(name)
print_name() # Python Guru
print(name) # Python Guru
封闭变量enclosing variables的概念是在嵌套函数nested functions的上下文中提到的。对于内层函数inner functions来说,外层函数outer functions中的变量既不是局部变量local variables,也不是全局变量global variable,而是 非局部变量nonlocal variables也称为封闭变量enclosing variables。例如:
name = "Zhang" # global variable
def outer_func():
name = "Python Guru" # enclosing variable
def inner_func():
name = "Tech Leader" # local variable
print(name)
inner_func() # inner_func prints its local variable
# will print "Tech Leader"
print(name) # print the enclosing variable
# will print "Python Guru"
return
outer_func()
# Tech Leader
# Python Guru
print(name) # print the global variable
# Zhang
如上所示,三个不同的名称代表三种不同类型的变量variables,它们由 LEGB 规则调用。
如果我们想在内部函数inner function中更改非本地变量nonlocal variable的值,则需要使用 nonlocal
关键字。
name = "Zhang" # global variable
def outer_func():
name = "Python Guru" # enclosing variable
def inner_func():
nonlocal name
name = "Tech Leader" # local variable
print(name)
inner_func() # inner_func prints its local variable
# will print "Tech Leader"
print(name) # print the enclosing variable
# will print "Tech Leader"!!!
return
outer_func()
# Tech Leader
# Tech Leader
print(name) # print the global variable
# Zhang
该语句与 global
关键字语句一样简单。
LEGB 规则定义了 Python 查找变量的顺序。
如果我们要在函数中改变全局变量global variable,需要 global
语句。
如果我们要在内部函数inner function中改变非局部变量nonlocal variables也称为封闭变量enclosing variables(你也可以理解为外层变量),则需要 nonlocal
语句。