Python中的作用域、global与nonlocal
2022/2/10 22:43:29
本文主要是介绍Python中的作用域、global与nonlocal,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
以下,以Python 3来介绍作用域相关的内容。
python 作用域分类
Python有四类作用域(Scope)。
- 局部(Local)作用域)
- 封闭(Enclosing)作用域(例如函数内部)
- 全局(Global)作用域
- 内置(Built-in)作用域
LEGB规则
在作用域中按名称去寻找对象(Python中一切皆对象)时,会按照LEGB规则去查找。 如果发生重名,也会按照LEGB规则,谁先被找到就用谁。
所谓LEGB规则,很简单,就是作用域查找顺序为:
Local -> Enclosing -> Global -> Built-in
以下,用示例代码来解释LEGB作用域,及其规则。
len = len([]) # (1) def a(): len = 1 # (2) def b(): len = 2 # (3) print(len) # (4) b() a()
len原本是Python的一个内置函数,在以上代码中被重新定义了三次。
在(1)中,右边的len([]),就是内置的len函数。 而左边的len =,则是新定义的全局变量,值为0。
在(2)中,又重新定义了len = 1。 这里是函数a的本地作用域,而对嵌套的函数b来说,则是Enclosing作用域。
在(3)中,再次重新定义了len = 2。 这是函数b的本地作用域。
在(4)中,打印len时,遵循LEGB规则,会打印Local的2。 如果没有(3),会打印Enclosing,也就是函数a里的1。 如果没有(2),会打印Global里的0。 如果没有(1),会打印< built-in function len >。
Python没有块级作用域(与其它语言不同点)
Python里是没有块级作用域(Block scope)的。以下述代码为例:
for i in range(10): pass print(i)
以上代码会打印出9。
这里是一个比较糟糕的设计。 如果有块级作用域,那么在for块结束后,就不应该能访问i。 而现在,会得到i的最后一个值。
更糟糕的是,如果range()里是0,那么for循环会直接退出。 这时再print(i),结果就是:
NameError: name ‘i’ is not defined
所以,虽然Python没有块级作用域,但是建议就当它有。 不要在代码块以外,使用代码块内定义的东西。
关键词global
前面只是谈及跨作用域的读取,还没谈及跨作用域的写入。
i = 0 def a(): i = 1 print('local:', i) a() print('global:', i)
以上代码的输出结果为:
local: 1 global: 0
也就是说,a函数里的i = 1,是定义一个新的局部变量,而非对全局变量的修改。
如果需要对全局变量i进行修改,则需要使用Python的global关键字。代码修改如下:
i = 0 def a(): global i i = 1 print('local:', i) a() print('global:', i)
以上代码输出结果为:
local: 1 global: 1
关键词nonlocal
修改Global变量的问题,可以用global关键字来解决; 修改Enclosing变量的问题,就需要使用nonlocal关键字。
i = 0 def a(): i = 1 def b(): nonlocal i i = 2 b() print(i) a()
以上代码的输出结果为2,这就是nonlocal的功效。
nonlocal不能代替global。 如果在上述代码的函数a中,就只能使用global。 因为,外层就是Global作用域了。
在多重嵌套中,nonlocal只会上溯一层; 而如果上一层没有,则会继续上溯。
def a(): i = 1 def b(): # i = 2 def c(): nonlocal i i = 3 c() print('b:', i) b() print('a:', i) a()
以上代码输出结果:
b: 3 a: 3
因为函数b中没有i,所以nonlocal上溯到了函数a中。
(注意:如果a中也没有,就回到了Global作用域,nonlocal会报错。)
如果以上代码中,函数b里的注释# i = 2去掉,则输出变为:
b: 3 a: 1
因为nonlocal只会上溯一层,到函数b,所以函数a中的i没有被修改。
这篇关于Python中的作用域、global与nonlocal的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南
- 2024-11-16`PyMuPDF4LLM`:提取PDF数据的神器
- 2024-11-16四种数据科学Web界面框架快速对比:Rio、Reflex、Streamlit和Plotly Dash
- 2024-11-14获取参数学习:Python编程入门教程