目录
-
命名空间以及查找顺序
1.局部命名空间 < 2.全局命名空间 < 3.内置命名空间
-
作用域&查找顺序
Local(局部变量) ,比如一个函数/方法内部。
Enclosing,包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B , 那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
Global 当前脚本最外层 。
Build In 内建变量/关键字等,最后被搜索。
查找顺序:L->E->G->B
-
新命名空间产生
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域, 其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,
code:if等语句不会引入新的命名空间
if True:
msg = "I like you!"
print(msg)
output:
I like you!
code:类或函数会引入新命名空间
def Tst():
msg_inner = "I come from china!"
print(msg_inner)
output:
Traceback (most recent call last):
File "XXX.py", line 532, in <module>
print(msg_inner)
NameError: name 'msg_inner' is not defined
-
全局变量&局部变量
例如在函数内部定义的变量拥有一个局部作用域,定义在函数外部的变量则是拥有一个全局作用域。
局部变量只有在其局部作用域内被使用,全局变量可以在整个程序中访问。
code:
# 定义一个全局变量
Count = 0
# 定义一个函数
def f_sum(a, b):
# 定义一个局部变量
Count = a + b
print('函数内是局部变量:%d' % Count)
return Count
f_sum(10, 3)
print('函数内是全局变量变量:%d' % Count)
output:
函数内是局部变量:13
函数内是全局变量变量:0
-
global 和 nonlocal关键字
修改全局变量:global
Count = 10
def ModifyGlobal():
global Count
print(Count)
Count = 16
print(Count)
ModifyGlobal()
print(Count)
output:
10
16
16
修改非局部&非全局变量:nonlocal
def Outer():
count = 10
def Inner():
nonlocal count
count = 18
print(count)
Inner()
print(count)
Outer()
output:
18
18
特别情况:
a = 10
def Test():
a = a + 1
print(a)
Test()
output:
Traceback (most recent call last):
File "XXX.py", line 577, in <module>
Test()
File "XXX.py", line 573, in Test
a = a + 1
UnboundLocalError: local variable 'a' referenced before assignment
因为a为局部变量,在使用时还没有定义,无法修改和使用
修改成全局变量参数传入:
a = 10
def Test(a):
a = a + 1
print(a)
Test(a)
print(a)
output:
11
10