2019年10月26日 / 193次阅读 / Last Modified 2019年10月26日
语法
基本上编程语言的变量作用域和引用规则都大同小异,python也不例外,不过还是要说一下,细节是魔鬼。
如果要很精确的来表达python变量的作用域和引用:内层代码可以直接使用或调用最靠近的外层变量所表示的对象,无需任何申明;但是如果要修改外层变量,就需要使用global或者nonlocal来申明。
>>> a = 1
>>> def test():
... a = 2
... def intest():
... print(a)
... intest()
...
>>> test()
2
>>> a
1
全局有a,test内也有a,这是两个不同的a,intest中可以直接使用a,这时的a是test中的,而不是全局的,因为test中的a更靠近intest函数。
直接引用有的时候会造成误解,python变量可以指向对象,函数也是对象,有些对象本就是可调用的对象(有__call__实现),这时对变量的直接引用,可以是直接使用其值,也可以是调用它,都可以!都无需申明!
global申明,这是全局的。
>>> a = 1
>>> def test():
... a = 2
... def intest():
... global a
... a = 11
... intest()
...
>>> test()
>>> a
11
在intest函数中,申明a来自全局,就是等于1的那个a,不是值为2的那个a哈,然后修改值为11,成功!
还可以这样,在某个内层空间中,直接定义一个全局的变量:
>>> def test():
... a = 2
... def intest():
... global b
... b = 22
... intest()
...
>>> b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> test()
>>> b
22
b一开始不存在,在test()函数被调用,intest函数被执行后,b才在全局范围内存在。
nonlocal用来申明,这不是一个本地的变量,但也不是全局。不是全局这个细节容易被忽略。
>>> c = 1
>>> def test():
... c = 2
... print(c)
... def intest():
... nonlocal c
... c = 22
... intest()
... print(c)
...
>>> test()
2
22
intest函数中申明nonlocal c,表示c不是本地的(intest内部),而是intest外部的非全局变量,这时只有test内部的c符合条件。为什么要强调c同时也不是全局的呢?请看下面的错误示例:
>>> c = 1
>>> def test():
... def intest():
... nonlocal c
... c = 22
... intest()
... print(c)
...
File "<stdin>", line 3
SyntaxError: no binding for nonlocal 'c' found
>>>
>>> c = 1
>>> def test():
... nonlocal c
... c = 111
...
File "<stdin>", line 2
SyntaxError: no binding for nonlocal 'c' found
可以看出,nonlocal要找的一定不是global范围的。
以上就是对python变量作用范围,以及global和nonlocal两个关键词使用的介绍。
-- EOF --
本文链接:https://www.pynote.net/archives/1398
《python变量的作用域和引用,global和nonlocal申明》有3条留言
©Copyright 麦新杰 Since 2019 Python笔记
The global statement can be used to indicate that particular variables live in the global scope and should be rebound there; the nonlocal statement indicates that particular variables live in an enclosing scope and should be rebound there. [ ]
nested scope最多能够有几层? [ ]
nonlocal还有一个名字,叫nested scope [ ]