python中变量作用域包括:
L (Local) 局部作用域,函数内部声明但没有使用global的变量
E (Enclosing) 闭包函数外的函数中,def或者lambda的本地作用域
G (Global) 全局作用域,函数中使用global声明的变量或在模块层声明的变量
B (Built-in) 内建作用域,python的内置类和函数等
当在函数中使用未认证的变量名时,将依照L->E->G->B的顺序搜索。
Python除了def/class/lambda 外,其他如: if/elif/else/ try/except for/while并不能改变其作用域。定义在他们之内的变量,外部还是可以访问。
1.变量在函数内部第一次出现,且在=左边,则为局部变量,作用在函数内部。
1 num = 100 2 def func(): 3 num = 200 #局部变量 4 print(num) 5 6 func() #输出200 7 print(num) #输出100
1 num = 100 2 def func(): 3 num = num + 200 #报错UnboundLocalError: local variable 'num' referenced before assignment,说明num是局部变量,在赋值前就被引用了 4 print(num) 5 6 func()
2.变量在函数内部第一次出现是在=右边,或作为函数参数,且之前已经定义了全局变量,那这里就是对全局变量的引用。
1 num = 100 2 def func(): 3 new = num + 200 4 print(new) 5 6 func() #输出300 7 print(num) #输出100
1 num = 100 2 def func(): 3 print(num) 4 5 func() #输出100
3.如果需要在函数内部引用并修改全局变量,则需使用global关键字。
1 num = 100 2 def func(): 3 global num 4 num = 'abc' 5 print(num) 6 7 func() #输出abc 8 print(num) #输出abc
4.nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量
1 #利用闭包返回一个计数器函数,每次调用它返回递增整数 2 def createCounter(): 3 i = 0 4 def counter(): 5 nonlocal i 6 i += 1 7 return i 8 return counter 9 10 11 # 测试: 12 counterA = createCounter() #返回counter()代码块及变量i=1 13 print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5 每次执行counterA()时,就是执行counter()代码块,改变i的值 14 counterB = createCounter() #返回counter()代码块及变量i=1 15 if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]: 16 print('测试通过!') 17 else: 18 print('测试失败!')