python作用域主要分为局部作用域、嵌套作用域、全局作用域、内建作用域,涉及三个关键字local、nonlocal、global,变量查找遵循从局部到全局的查找顺序。
四个作用域特点
局部作用域
局部作用域指的就是函数内部的作用域,如下代码,x 所处的区域就是局部作用域
def func():
x = 10
嵌套作用域
嵌套作用域主要在多个函数嵌套的时候才有所体现,表示某个函数外部嵌套的函数所在的作用域,x所处位置就是嵌套作用域。
def func():
x = 10
def innner_func():
y = 20
如果外部函数还有更外层的函数嵌套,他也是属于嵌套作用域。如下所示y所处的也是嵌套作用域。
全局作用域
全局作用域指的是当前模块所处的区域,如下z所处的区域
z = 30
def func():
x = 10
def innner_func():
y = 20
内建作用域
内建作用域是特质python api内置的一些操作,例如 len 、max等函数,无需声明就可使用。
作用域的查找顺序
python遵循从内到外的查找,顺序,我们下面写个例子。
- 全局作用域、嵌套作用域、局部作用域不存在该变量/函数,内建存在该变量和函数,在最内层函数调用,会在内置作用域查找。如下所示,len为内建作用域
def func():
def innner_func():
print(len('123'))
innner_func()
func()
- 全局作用域存在、嵌套作用域、局部作用域不存在该变量/函数,在最内层函数调用,会在全局作用域查找。
x = 100
def func():
def innner_func():
print(x) # 输出100
innner_func()
func()
- 嵌套作用域、局部作用域不存在该变量/函数,在最内层函数调用,会在上层嵌套作用域查找。
def func():
x = 100
def innner_func():
print(x) # 输出100
innner_func()
func()
-
局部作用域就更简单了
def func():
x = 100
print(x) # 输出100
func()
涉及关键字
为什么会有local、nonlocal、global这些关键字呢,原因在于如上边的查找顺序,只能读取外部作用域的值,当我们修改的时候,python并不能理解这个操作是赋值,还是修改上层作用域。
local
local指本地作用域,也就是局部变量,我们修改局部变量只需要重新赋值即可,所以无需声明。
def func():
x = 100
x = 200
x = 300
print(x) # 输出300
func()
nonlocal
假如上述函数有个外部的作用域,如下所示,输出100
def outer_func():
x = 1
def func():
x = 100
print('change nonlocal is %s' % x) # 输出100
func()
print('outer x is %s' % x) # 输出100
outer_func()
输出:
change nonlocal is 100
outer x is 1
但是有时候想修改 x=1这个赋值,想修改为100,那么怎么做呢,就是给x声明nonlocal即可
def outer_func():
x = 1
def func():
nonlocal x
x = 100
print('change nonlocal is %s' % x) # 输出100
func()
print('outer x is %s' % x) # 输出100
outer_func()
输出:
change nonlocal is 100
outer x is 100
global
和上述同理,修改全局变量,声明global即可
x = 2
def outer_func():
x = 1
def func():
global x
x = 100
print('change global is %s' % x) # 输出100
func()
print('outer x is %s' % x) # 输出100
outer_func()
print('global x is %s' % x)
输出:
change global is 100
outer x is 1
global x is 100