作用
nonlocal允许对嵌套的函数作用域中的名称进行赋值,并且把这样的名称的作用域查找限制在嵌套的函数内。
nonlocal限制查找在嵌套的函数域内,且可以在函数域内进行赋值修改。
例子
1 | def tester(start): |
函数nested中print方法内的state变量引用了上一层tester函数中的state。
如果仅仅是引用变量,则不会出现问题,若是不使用nonlocal情况下对变量进行赋值操作
,则出现报错:
1 | def tester(start): |
state因为在nested中没有被定义,所以无法被赋值,但可以引用上一层tester函数。
如果要定义,则需要用nonlocal函数对其进行声明:
1 | def tester(start): |
边界情况
- nonlocal对象必须已经在一个嵌套的def作用域中被赋值过,否则会报错。(global则不需要预先对变量进行赋值。)
报错代码如下:
1 | def tester(start): |
因为在state被nonlocal处理之前并没有对state进行赋值!
nonlocal只会在嵌套def的作用域内查找,查找范围永远不会出def作用域范围,即便在最外层全局有了定义这个变量,也不会去查找。如果要去全局变量查询,则使用global。
nonlocal查询会
逐级往上
查询,查询到一个立马返回
,也就是会就近查询。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16state = 0
def tester(start):
state = 1
def cisco(middle):
state = 2
def nested(label):
nonlocal state
print(label, state)
return nested
return cisco
F=tester(0)
F(1)('spam')
输出结果为
spam 2因为在cisco这个函数中已经存在了state=2的赋值,所以不会再查询cisco上一层tester中的state。就近返回了state=2。