博客
关于我
Python基础:11变量作用域和闭包
阅读量:800 次
发布时间:2023-03-07

本文共 2573 字,大约阅读时间需要 8 分钟。

变量作用域与闭包

在编程中,变量的作用域是理解代码行为的关键概念。一个变量可以属于局部作用域或全局作用域。定义在函数内的变量具有局部作用域,而在模块最高级别定义的变量则属于全局作用域。

全局变量的特点是除非被显式删除,否则它们会一直存在到脚本运行结束,并且可以在所有函数中访问。相比之下,局部变量的生命周期仅取决于其定义函数的执行阶段。

在Python中,变量查找遵循局部-外部-全局-内建(LEGB)的顺序优先级。在局部作用域未找到变量时,才会在外部作用域、全局作用域和内建作用域中依次查找。如果仍未找到,则会抛出NameError异常。因此,局部变量可以“隐藏”或覆盖全局变量。

由于闭包和嵌套函数的引入,作用域的层次变得更复杂。变量查找的优先级顺序变为:局部、外部、全局和内建。需要注意的是,只有def、class和lambda等语句会产生新的作用域,而if、try、for等语句不会创建新的作用域。

例如,在以下函数中,变量a仍然属于局部作用域,而不是由if语句引入的新作用域:

def foo():
if True:
a = 2
print(a)

a可以在print语句中访问,因为它属于局部作用域。

在函数内部对全局变量进行赋值时,必须使用global声明,否则会导致UnboundLocalError异常。例如:

>>> gv = 4
>>> def bar():
... gv += 2
...
Traceback (most recent call last):
File "
", line 1, in
File "
", line 2, in bar
UnboundLocalError: local variable 'gv' referenced before assignment

此外,局部变量可以覆盖全局变量,需要谨慎处理。例如:

>>> def foo():
... lv = 2
... gv = 3
... print('lv is %d, gv is %d' % (lv, gv))
...
>>> gv = 4
>>> foo()
lv is 2, gv is 3

在函数内部明确使用全局变量时,必须使用global声明。

在Python2.1之前的版本中,函数嵌套会导致作用域扩展问题。例如:

def foo():
m = 3
def bar():
n = 4
print(m + n)
print(m)
bar()

在Python2.1之前运行会导致错误,但在现代Python版本中可以正常运行。

Python的lambda匿名函数遵循与标准函数相同的作用域规则。一个lambda表达式定义了一个新的作用域,该作用域中的变量不能在程序其他部分访问。

闭包

闭包(Closure)是指在内部函数中引用外部作用域变量的函数。闭包通过引用外部作用域的变量实现,其行为类似于记忆化。闭包的环境包括外部函数中的变量和上下文。

例如:

def line_conf():
b = 15
def line(x):
return 2 * x + b
return line
my_line = line_conf()
print(my_line(5)) # 输出 25

line函数引用了line_conf作用域中的变量b,因此my_line携带了b的值。

闭包的一个重要特性是它会携带其创建时所依赖的环境变量。即使外部函数退出,闭包仍然保留环境变量的引用。

例如:

def counter(start_at=0):
count = [start_at]
def incr():
count[0] += 1
return count[0]
return incr
count = counter(5)
print(count()) # 输出 6
print(count()) # 输出 7
count2 = counter(100)
print(count2()) # 输出 101
print(count()) # 输出 8

闭包会携带外部函数的环境变量。

需要注意的是,闭包不能直接修改外部变量,除非使用nonlocal关键字(Python3引入)。例如:

def counter2(start_at=0):
count = start_at
def incr():
count += 1
return count
return incr
count = counter2(5)
print(count()) # 会抛出UnboundLocalError

此外,闭包的环境变量可以通过func_closure属性访问。例如:

output = '
%s
'
w = x = y = z = 1
def f1():
x = y = z = 2
def f2():
y = z = 3
def f3():
z = 4
print(output % ('w', id(w), w))
print(output % ('x', id(x), x))
print(output % ('y', id(y), y))
print(output % ('z', id(z), z))
return f3
return f2
my_f3 = f3()
print(my_f3)

运行结果显示,闭包会记录外部变量的引用。

总结来说,变量作用域和闭包是理解Python函数行为的关键概念。通过正确管理局部变量和闭包,可以编写更高效和可靠的代码。

转载地址:http://sxofk.baihongyu.com/

你可能感兴趣的文章
python基于flask搭建http服务(二)—— 实现Excel上传、数据清洗、入库
查看>>
python基于flask搭建http服务(三)—— 使用gunicorn部署项目
查看>>
python基于flask搭建http服务(一)—— 实现数据查询和Excel导出
查看>>
Python块键盘/鼠标输入
查看>>
python在心理学研究中的应用有哪些_心理学在线研究可用平台简介和应用进展
查看>>
python在使用HTMLTestRunner时,报告为空,错误提示<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf_8'>...
查看>>
python在gpu上运行_【python】python开启GPU加速
查看>>
Python在def函数中使用for循环
查看>>
Python在def函数中使用for循环
查看>>
Python在Conda环境中,但在Windows虚拟环境中没有激活
查看>>
python系列【仅供参考】:python pip 错误 ModuleNotFoundError: No module named pip._internal 解决办法
查看>>
python图像条状状噪声,使用PYTHON PIL从验证码图像中删除背景嘈杂的线条
查看>>
Python图像处理:从内存加载jpeg
查看>>
python固定后缀(名物化词汇)词频统计:抽取+统计+可视化
查看>>
python商品评论数据采集与分析可视化系统 Flask框架 requests爬虫 NLP情感分析 毕业设计 源码
查看>>
python商品数据分析可视化系统(带爬虫)京东销售数据分析 计算机毕业设计 源码下载
查看>>
python商品库存管理系统 django框架 商品网站 MySQL数据库 源码下载 计算机毕业设计
查看>>
Python哪个版本最稳定好用2023.10.19
查看>>
Python和黑客技术的渊源
查看>>
Python和RF编写接口自动化
查看>>