关于nonlocal的疑惑
def fun1():x = 5
def fun2():
nonlocal x
x *= 2
return x
return fun2()
这里的nonlocal会将外部变量x修改吗,还是会说,外部的x = 5 不会被修改,只会被调用? 这个语句会把内部和外部的x,变为一体,同时,如果内部x发生变化,会修改外部x 本帖最后由 叼辣条闯世界 于 2021-8-27 20:30 编辑
python官方是这样说的
非局部声明变量指代的已有标识符是最近外面函数的已声明变量,但是不包括全局变量。这个是很重要的,因为绑定的默认行为是首先搜索本地命名空间。nonlocal声明的变量只对局部起作用,离开封装函数,那么该变量就无效。
非局部声明不像全局声明,我们必须在封装函数前面事先声明该变量
非局部声明不能与局部范围的声明冲突
官网的解释虽然很好,但是不好理解,我们直接使用代码进行理解:
count = 1
def a():
count = 'a函数里面' #如果不事先声明,那么函数b中的nonlocal就会报错
def b():
nonlocal count
print(count)
count = 2
b()
print(count)
if __name__ == '__main__':
a()
print(count)
结果是
a函数里面
2
1
该代码就可以很好的解释了,第一行的count和a()函数中的count是两个变量,而a()函数中的count变量只是在该函数内部起作用,因为它是一个局部变量。
nonlocal只能在封装函数中使用,在外部函数先进行声明,在内部函数进行nonlocal声明,这样在b()函数中的count与a()中的count是同一个变量。
nonlocal错误的使用方法
1.在外部函数进行声明
count = 1
def a():
#nonlocal count #这种声明方法肯定报错,
def b():
nonlocal count #在a()函数中没有提前声明,所以报错
print(count)
count = 2
b()
print(count)
if __name__ == '__main__':
a()
print(count)
报错代码:
File "G:/python/test.py", line 5
nonlocal count
^
SyntaxError: no binding for nonlocal 'count' found
2.外部函数中变量声明为global
count = 1
def a():
global count
count = 'a函数里面'
def b():
nonlocal count
print(count)
count = 2
b()
print(count)
if __name__ == '__main__':
a()
print(count)
报错代码:
File "G:/python/test.py", line 7
nonlocal count
^
SyntaxError: no binding for nonlocal 'count' found 要能 "被修改",那肯定需要"被调用"呀。
因为你声明 x 是 nonlocal , 所以它会"往上找",找外层的x变量,找到了 fun1的局部变量 x ,发现x=5,可以用, 于是就用了。
所以,这里的修改操作 操作的就是 外部的x 叼辣条闯世界 发表于 2021-8-27 20:27
python官方是这样说的
外部函数中变量声明为global
为啥会报错?是因为global将外部变量申明为全局变凉了,所以nonlocal找不到外部变量了吗? Jerry~Mouse 发表于 2021-8-27 21:31
外部函数中变量声明为global
为啥会报错?是因为global将外部变量申明为全局变凉了,所以nonlocal找不到 ...
因为和global的声明 起冲突了。
nonlocal count 用的是外层的 count,
你再声明它同名的count是最外层的global,那就超出了nonlocal的"查找范围scope"了。
The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.
Names listed in a nonlocal statement, unlike to those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).
Names listed in a nonlocal statement must not collide with pre-existing bindings in the local scope.
页:
[1]