作用域
如果一个名称绑定在一个代码块中,则其为代码块的局部变量;除非声明为
nonlocal
或global
.
global
语句可被用来表明特定变量生存于全局作用域并且应当在其中被重新绑定;nonlocal
语句表明特定变量生存于外层作用域中并且应当在其中被重新绑定。


- 局部赋值(这是默认状态)不会改变 scope_test 对 spam 的绑定;
nonlocal
赋值会改变 scope_test 对 spam 的绑定;- 而
global
赋值会改变模块层级的绑定。
global 变量
如果名称绑定在模块层级,则为
global
变量,即全局变量。如果
global
语句出现在一个代码块中,则所有对该语句所指定名称的使用都是在最高层级命名空间内对该名称绑定的引用。global
变量不得被定义为正式形参,也不得出现于 for 循环的控制目标、class 定义、函数定义、import 语句或变量标注之中。
nonlocal 变量
nonlocal
语句会使得所列出的名称指向之前在最近包含作用域中绑定的除全局部变量以外的变量。如果指定名称不存在于任何包含函数作用域中则将在编译时引发
SyntaxError
。nonlocal
语句中列出的名称不得与之前存在于局部作用域中的绑定相冲突。
自由变量
如果变量在一个代码块中被使用但不是在其中定义,则为自由变量。
自由变量的名称解析发生于运行时而不是编译时。这意味着以下代码将打印出 42:
i = 10 def f(): print(i) i = 42 f()
特殊地,自由变量也可以指向全局变量而不必声明为全局变量,这个看上面例子应该很好理解。
nested scope
嵌套作用域:在一个定义范围内引用变量的能力。例如,在另一函数之内定义的函数可以引用前者的变量。
请注意嵌套作用域默认只对引用有效而对赋值无效。局部变量的读写都受限于最内层作用域。
类似的,全局变量的读写则作用于全局命名空间。
通过
nonlocal
关键字可允许写入外层作用域。