python中引用变量的顺序为:当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量。
而python中unlocal的作用为变当前作用域局部变量为最临近外层(非全局)作用域变量。
而global的作用为变当前作用域局部变量为当前模块中的全局变量。
先来看下面一个简单的例子:
def test_nonlocal():
dd = 0
def test2():
dd += 2
test2()
print(dd)
test_nonlocal()
Traceback (most recent call last):
在这里会出现错误,可以看到,dd在这里没有定义,这是因为dd是在test_unlocal中定义的。当在内部函数引用外部函数的变量时,它会认为这是一个内部函数的局部变量,但是在内部函数test2中,因为没有调用dd的值,所以会报错。
这里unlocal的作用就会显现出来了:
def test_nonlocal():
dd = 0
def test2():
nonlocal dd
dd += 2
test2()
print(dd)
test_nonlocal()
>>>2
加上nonlocal,就是说明将dd的作用域提到上面临近一层,也就是test_nonlocal那一层
但是在内部函数直接引用倒是没有问题,也就是说不作任何修改,直接用。
def test_nonlocal():
dd = 0
def test2():
print(dd)
test2()
test_nonlocal()
>>>0
这样就不会报错。
def test_nonlocal():
dd = 0
def test2():
def test3():
nonlocal dd
dd += 2
test3()
test2()
print(dd)
test_nonlocal()
>>>2
def test_nonlocal():
dd = 0
def test2():
def test3():
dd = 3
def test4():
nonlocal dd
dd += 2
print(dd)
test4()
test3()
test2()
print(dd)
test_nonlocal()
>>>5
>>>0
但在上面的例子中,最邻近外层为test3,故先输出5,再输出0
但当最邻近外面为全局变量时,便会报错:
dd = 0
def test_nonlocal():
nonlocal dd
dd += 2
print(dd)
test_nonlocal()
File "D:/python/leetcode/test3.py", line 3
nonlocal dd
SyntaxError: no binding for nonlocal 'dd' found
所以nonlocal只能引用到最外层非全局变量。
对于global语句来说,性质与nonlocal差不多,只不过global是将变量直接变为全局变量。
dd = 0
def test_global():
def test2():
dd += 2
test2()
test_global()
Traceback (most recent call last):
File "D:/python/leetcode/test1.py", line 7, in
test_nonlocal()
File "D:/python/leetcode/test1.py", line 6, in test_nonlocal
test2()
File "D:/python/leetcode/test1.py", line 5, in test2
dd += 2
UnboundLocalError: local variable 'dd' referenced before assignment
上述代码同样报错
dd = 0
def test_global():
def test2():
global dd
dd += 2
print(dd)
test2()
test_global()
>>>0
同样的,也是可以引用的。
dd = 0
def test_global():
def test2():
global dd
dd += 2
dd += 2
test2()
test_global()
Traceback (most recent call last):
File "D:/python/leetcode/test1.py", line 9, in
test_nonlocal()
File "D:/python/leetcode/test1.py", line 7, in test_nonlocal
dd += 2
UnboundLocalError: local variable 'dd' referenced before assignment
但是,在test2中定义的dd为global,运用作用域也仅限于在test2中,在外层应用时,同样也会出错。
dd = 0
def test_global():
def test2():
global dd
dd += 2
global dd
test2()
dd += 2
print(dd)
test_global()
>>>4
在外层使用时,同样需要使用global
3.总结
当在不同的作用域调用变量是,一定要注意变量的作用域范围。
unlocal的作用为变当前作用域局部变量为最临近外层(非全局)作用域变量。
而global的作用为变当前作用域局部变量为当前模块中的全局变量。
当试图去修改,不同作用域中的变量的值时,python会自动创建一个在那个作用域里面的同名变量,变量的作用范围仅限于此作用域。但是仅仅是引用变量确是可以引用的。
下面再看一个简单的例子:
def test():
def local_test():
spam = "local spam"
def nonlocal_test():
nonlocal spam
spam = "nonlocal spam"
def global_test():
global spam
spam = "global spam"
spam = "test spam"
local_test()
print("After local assignmane:", spam)
nonlocal_test()
print("After nonlocal assignment:",spam)
global_test()
print("After global assignment:",spam)
这说明在global_test中,创建的是全局变量。