基于Python闭包及其作用域详解

发布时间 - 2026-01-11 02:59:06    点击率:

关于Python作用域的知识在python作用域有相应的笔记,这个笔记是关于Python闭包及其作用域的详细的笔记

如果在一个内部函数里,对一个外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被称为闭包(closure),而这个被内部函数引用的变量则被成为自由变量

闭包和函数调用没多少相关,而是关于使用定义在其他作用域的变量

命名空间和作用域

我们把命名空间看做一个大型的字典类型(Dict),里面包含了所有变量的名字和值的映射关系。在 Python 中,作用域实际上可以看做是“在当前上下文的位置,获取命名空间变量的规则”。在 Python 代码执行的任意位置,都至少存在三层嵌套的作用域:

最内层作用域,最先搜索,包含所有局部变量(Python 默认所有变量声明均为局部变量)

所有包含当前上下文的外层函数的作用域,由内而外依次搜索,这里包含的是非局部也非全局的变量

一直向上搜索,直到当前模块的全局变量

最外层,最后搜索的,内置(built-in)变量

 scopes = {
 "local": {"locals": None,
    "non-local": {"locals": None,
       "global": {"locals": None,
         "built-in": ["built-ins"]}}},
}

除了默认的局部变量声明方式,Python还有global和nonlocal两种类型的声明(nonlocal是Python3.x之后才有的),其中nonlocal是指最内层之外,global以内的变量。必须强调的是,最内层局部作用域对外层作用域的变量只有只读(read-only)的访问权限。比如下列的例子

x = 100
def main():
 x += 1
 print (x)
main()
UnboundLocalError Traceback (most recent call last)
<ipython-input-2-9ed43e483a17> in <module>()
  3 x += 1
  4 print(x)
----> 5 main()
<ipython-input-2-9ed43e483a17> in main()
  1 x = 100
  2 def main():
----> 3 x += 1
  4 print(x)
  5 main()
UnboundLocalError: local variable 'x' referenced before assignment

这里抛出UnboundLocalError,是因为main()函数内部的作用域对于全局变量x仅有只读权限,想要在main()中对x进行改变,不会影响全局变量,而是会创建一个新的局部变量,显然无法对还未创建的局部变量直接使用x += 1, 因为x未绑定到任何对象上。如果想要获得全局变量的完全引用,则需要global声明:

x = 100
def main():
 global x
 x += 1
 print(x)
main()
print(x) # 全局变量已被改变

# result: 
# 101
# 101

闭包

闭包和函数调用没多少相关,而是关于使用定义在其他作用域的变量。

看了上面的Python作用域规则后,我们可以仿照JavaScript写一个计数器的闭包:

"""
/* JavaScript Closure example */
var inc = function(){ 
 var x = 0;
 return function(){
 console.log(x++);
 };
};
var inc1 = inc()
var inc2 = inc()
"""

# Python
def inc():
 x = 0
 def inner():
  nonlocal x
  x += 1
  print(x)
 return inner
inc1 = inc()
inc2 = inc()
inc1()
inc1()
inc1()
inc2()


# result:
# 1
# 2
# 3
# 1

在这里,全局环境下不能获取到inc()中的局部变量x的,但是我们返回了inc()内部函数inner(),而inner()对inc()中的局部变量是有访问权限的。也就是说inner()将inc()局部作用域打包发送给了inc1和 inc2,从而使他们各自独立拥有了一块封闭起来的作用域,不受其他运行环境和全局变量的影响,因此称之为闭包。

上述代码中inc1和inc2各自有一块封闭起来的作用域,可以通过Online Python Tutor 可视化运行工具看相应的运行结果

这篇基于Python闭包及其作用域详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# 闭包和作用域  # Python编程中闭包的变量作用域问题解析  # Python 闭包  # 函数分隔作用域  # nonlocal声明非局部变量操作示例  # 详解Python循环作用域与闭包  # 浅谈Python中的作用域规则和闭包  # 基于Python函数的作用域规则和闭包(详解)  # Python全栈之作用域和闭包  # 全局变量  # 给大家  # 的是  # 访问权限  # 运行环境  # 在这里  # 是因为  # 看了  # 是有  # 是指  # 已被  # 均为  # 我们可以  # 可以通过  # 给了  # 希望能  # 不受  # 才有  # 还未  # 被称为 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何与Inertia.js和Vue/React构建现代单页应用  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  java中使用zxing批量生成二维码立牌  canvas 画布在主流浏览器中的尺寸限制详细介绍  深圳网站制作的公司有哪些,dido官方网站?  如何在IIS管理器中快速创建并配置网站?  进行网站优化必须要坚持的四大原则  如何在企业微信快速生成手机电脑官网?  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  网站建设整体流程解析,建站其实很容易!  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  教你用AI润色文章,让你的文字表达更专业  在线教育网站制作平台,山西立德教育官网?  Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程  HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】  Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】  微信小程序 require机制详解及实例代码  Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  Bootstrap CSS布局之列表  如何在建站之星网店版论坛获取技术支持?  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  如何在阿里云虚拟主机上快速搭建个人网站?  C++用Dijkstra(迪杰斯特拉)算法求最短路径  1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤  Linux系统命令中tree命令详解  ,交易猫的商品怎么发布到网站上去?  如何在阿里云香港服务器快速搭建网站?  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  如何为不同团队 ID 动态生成多个独立按钮  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  如何快速搭建安全的FTP站点?  javascript中对象的定义、使用以及对象和原型链操作小结  如何用免费手机建站系统零基础打造专业网站?  悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】  作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  Python自然语言搜索引擎项目教程_倒排索引查询优化案例  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  大连 网站制作,大连天途有线官网?