当前结论,基于 python3,不一定适用于 python2.
作用域分类
L (Local)
局部作用域(一般指函数,在函数内部定义的则是局部变量)E (Enclosing)
闭包函数外的函数中G (Global)
全局作用域B (Built-in)
内建作用域
访问规则
-
访问规则链:
L => E => G => B -
解释一下:
从局部作用域
开始查找,如果局部作用域
不存在,则往上一层(也就是指嵌套函数)开始查找,如果上一层也不存在,则继续向上,一直到(这个过程都是与 2. 闭包函数外的函数)全局作用域
,如果全局作用于也不存在,则在内建作用域
查找,如果依然不存在,则报错is not defined
.
内部访问外部变量
# 全局作用域
x=10
# 第一层局部作用域
def outer():
y=20;
print(x)
# 第二层局部作用域
def inner():
z=30
print(f"x={x},y={y}")
inner()
outer()
# 输出内容
# 10
# x=10,y=20
内部修改外部变量
局部作用域
中直接修改:不生效;
在 局部作用域
中修改 全局变量
时,由于 x=20
的赋值操作,默认是在 局部作用域
创建了一个叫 x
的局部变量,而不是与 全局变量
关联起来。
# 全局作用域
x=10
# 局部作用域
def changeNum():
x=20
print(x) # 20
changeNum()
print(x) # 10
局部作用域
中,先使用全局变量,然后再修改:
这是因为,python
中,当你在局部变量中使用一个变量时,它会默认是在局部变量中的,会形成类似于 JavaScript
中 let
,const
那种 暂时性死区
。
所以在 局部作用域
中,只要有变量赋值操作,也就是创建操作,那就不可以在此之前(基于当前局部作用域)调用该变量;
否则报错:UnboundLocalError: local variable 'x' referenced before assignment
# 全局作用域
x=10
# 局部作用域
def changeNum():
print(x) # UnboundLocalError: local variable 'x' referenced before assignment
x=20
print(x)
changeNum()