Python 闭包的高级用法详解

    所谓闭包,就是指内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程,这个内函数称之为闭包函数。可以理解为是函数式编程中的封装。



    内部函数可以使用外部函数定义的属性:外部函数调用后,返回内部函数的地址,完成内部函数的调用。

在这里插入图片描述



def outer():num = 100def inner():return numreturn innerresult = outer()
print(f'外部函数调用后,返回内部函数的地址:{result}')
print('通过内部函数的地址,完成内部函数的调用,使用外部函数定义的属性值为:', result())


    一般写法和闭包写法的对比:



    一般写法,在 传入的 x 和 y 不变情况下,每次调用函数时,都要重复传入相同的 x、y 参数。



在这里插入图片描述



def cal(x,y,z):print(x+y+z)cal(2,3,4)
cal(2,3,5)
cal(2,3,6)
cal(2,3,7)
cal(2,3,8)


    闭包写法,在x、y固定的情况下,只需要通过调用内部函数去传 z参数就可以了。如果要计算的结果太多,要传的 z 可能好多,也可以通过循环去实现传参,减少重复调用函数。



在这里插入图片描述



def cal(x,y):def cal_in(z):print(x+y+z)return cal_inresult = cal(2,3)
result(4)
result(5)
result(6)
result(7)
result(8)


    全局变量对闭包函数调用时所引用的变量究竟有没有影响?



    可见,当调用闭包函数时,是直接调用了外部函数变量
n = 3, 而不是全局变量 n = 4, 因此结果为 27。也证明了执行函数时,它的优先级是先搜索内部作用域的变量,全局变量对闭包函数的执行并没有影响。



在这里插入图片描述



def pow1():n = 3def pow2(x):return x ** nreturn pow2n = 4result = pow1()
print(result(3))


    closure是内部函数的一个属性,用来保存环境变量,返回的是一个元组,每一项都是闭包函数引用的外部变量。可以通过cell_contents 将被引用的变量打印出来。



    首先打印 result 的类型,可见是一个函数类型,证明在这个函数里面,我们可以将另外一个函数作为这个函数的返回值去进行返回的。 打印 closure, 得出内部函数的属性所对应的环境变量,可见它是一个元组类型。最后通过 cell_contents去获取变量的值。要注意的是,由于环境变量是一个元组,cell_contents是没有元组直接获取变量值的属性,因此必须先通过索引去获取你要的数据,否则会有报错。



在这里插入图片描述



    假设把 n = 3 放到最外层,变成全局变量,结果会一样吗?



    可见结果已经有刚才的 27 变成了 81。由于 n = 3 已经由局部变量变成了全局变量,当调用 pow2(x)时,并没有引用 pow1() 的变量,因此它并不是闭包函数,只是一个普通的嵌套函数,当pow2(x)搜索内部作用域没找到 n 的变量,就会搜索全局变量,由于全局变量同时存在 n = 3 和 n = 4, 这时变量就相当于 n = 4, 结果就是 3的4次方为81,而不是刚才执行闭包函数时的27了。



在这里插入图片描述



    同样,根据刚才介绍的 closure 概念,我们可以通过打印 closure 去验证是否闭包。



    可见结果为 None, 证明这不是闭包函数。



在这里插入图片描述



    当 n 未定义的情况下出现的报错:



在这里插入图片描述



def pow1():n = 3def pow2(x):n +=1return x ** nreturn pow2result = pow1()
print(result(3))


    解决报错的方法:可以用 nonlocal 关键字声明 一个变量, 表示这个变量不是局部变量空间的变量,需要向上一层变量空间找这个变量。



    可见添加 nonlocal后,闭包函数可以正常调用 n = 3 并执行累加。因此当调用第一次时,结果为 81, 调用第二次时,结果为 243, n 相当于变成了5



在这里插入图片描述



    再看另外一个循环的例子,循环中变量分别是1、2,但实际最终返回的结果为4,4。 原因是返回的函数引用了变量i,但它并非立刻执行。等到2个函数都返回时,它们所引用的变量i已经变成了2。从打印 cell_contents 结果可见。

在这里插入图片描述



def pow1():n=2L = []for i in range(1,3):def pow2():return i ** nL.append(pow2)return Lf1,f2 = pow1()
print(f1())
print(f2())
print(f1.__closure__)
print(f2.__closure__)
print(f1.__closure__[0].cell_contents)
print(f2.__closure__[0].cell_contents)


    要改变分别执行变量1、2, 让pow2() 形成闭包。可见被引用的变量也分别是1,2,返回的结果就是我们预期的1,4



在这里插入图片描述



def pow1():n=2L = []for i in range(1,3):def extra(i):def pow2():return i ** nreturn pow2L.append(extra(i))return Lf1,f2 = pow1()
print(f1())
print(f2())
print(f1.__closure__)
print(f2.__closure__)
print(f1.__closure__[0].cell_contents)
print(f2.__closure__[0].cell_contents)


    关于更多闭包的高级用法疑问,欢迎留言!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/15154.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux_web控制台-cockpit

1、安装cockpit [rootlocalhost ~]# dnf install cockpit -y 2、启动cockpit服务并查运行状态 [rootlocalhost ~]# systemctl start cockpit [rootlocalhost ~]# systemctl status cockpit 2、设置开机启动 [rootlocalhost ~]# vim /usr/lib/systemd/system/cockpit.servi…

局域网桌面监控软件哪个好用?良心推荐

如何有效地监控和管理内部员工的计算机使用行为,防范潜在的安全风险,提高工作效率,是众多企业管理者关注的焦点。 而一款优秀的局域网桌面监控软件无疑能为企业的IT治理提供有力支撑。 小编在此给大家推荐一款好用的局域网桌面监控软件——域…

5. C++网络编程-UDP协议的实现

UDP是无连接的。 UDP Server网络编程基本步骤 创建socket,指定使用UDP协议将socket与地址和端口绑定使用recv/send接收/发送数据 由于UDP是无连接的,直接侦听就行使用close关闭连接 这个UDP接收数据的时候用的API是recvfrom,发送数据是sendto

MCS-51伪指令

上篇我们讲了汇编指令格式,寻址方式和指令系统分类,这篇我们讲一下单片机伪指令。 伪指令是汇编程序中用于指示汇编程序如何对源程序进行汇编的指令。伪指令不同于指令,在汇编时并不翻译成机器代码,只是会汇编过程进行相应的控制…

已有yarn集群部署spark

已有yarn集群的情况下,部署spark只需要部署客户端。 一、前提条件 已部署yarn集群,部署方式参考:https://blog.csdn.net/weixin_39750084/article/details/136750613?spm1001.2014.3001.5502,我部署的hadoop版本是3.3.6已安装j…

Android Compose 九:常用组件列表 简单使用

遇事不决 先看官方文档 列表和网格 如果不需要任何滚动,通过Column 或 Row可以使用verticalScroll() 使Column滚动 Column(modifier Modifier.verticalScroll(rememberScrollState())) {for (i in 0..50){Text(text "条目>>${i}")}}显示大量列表…

从0开始linux(3)——如何读写文件

欢迎来到博主的专栏——从0开始linux 博主ID:代码小豪 文章目录 创建普通文件用文本编辑器nano写入文件如何读取文件cat命令less命令head和tail 我们前面已经了解和如何操作文件,但是目前认识的文件类型分为两类,一类是目录文件、另一类是普通…

【C#上位机应用开发实战】—— 通信模块的基础与实践

🚀 引言 在工业自动化、设备监控、物联网(IoT)等领域,上位机软件扮演着至关重要的角色。作为连接人与设备的桥梁,上位机软件不仅需要提供友好的用户界面,更需要具备高效、稳定的通信能力。今天&#xff0c…

ASP+ACCESS教师档案管理系统

3.1 系统功能模块图 3.2 E-R模型图 3.3 系统使用流程图 3.4 各个模块功能简介: 本系统分为五个功能模块,它们分别是教师信息录入模块、教师信息修改模块、教师信息查询模块、教师信息打印模块。 下面分别介绍各个模块的功能用途&#x…

第 398 场 LeetCode 周赛题解

A 特殊数组 I 模拟&#xff1a;遍历数组判断是否是一个特殊数组 class Solution { public:bool isArraySpecial(vector<int>& nums) {int r 0;while (r 1 < nums.size() && nums[r 1] % 2 ! nums[r] % 2)r;return r nums.size() - 1;} };B 特殊数组 I…

计网(部分在session学习章)

TCP/UDP TCP:面向连接,先三次握手建立连接,可靠传输。 UDP:无连接,不可靠,传递的快。 TCP可靠传输 1.分块编号传输; 2.校验和,校验首部和数据的检验和,检测数据在传输中的变化; 3.丢弃重复数据; 4.流量控制,TCP 利⽤滑动窗⼝实现流量控制。TCP的拥塞控制采⽤…

基于Matlab卷积神经网络人脸识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 人脸识别作为计算机视觉领域的关键技术之一&#xff0c;具有广泛的应用前景&#xff0c;如安全…

Add object from object library 从对象库中添加内置器件

Add object from object library 从对象库中添加内置器件 正文正文 对于 Lumerical,有些时候我们在使用中,可能需要从 Object library 中添加器件,通常我们的做法是手动添加。如下图所示,我们添加一个 Directional Coupler 到我们的工程文件中: 但是这种操作方式不够智能…

基于HTML5和CSS3搭建一个Web网页(二)

倘若代码中有任何问题或疑问&#xff0c;欢迎留言交流~ 网页描述 创建一个包含导航栏、主内容区域和页脚的响应式网页。 需求: 导航栏: 在页面顶部创建一个导航栏&#xff0c;包含首页、关于我们、服务和联系我们等链接。 设置导航栏样式&#xff0c;包括字体、颜色和背景颜…

上门服务系统开发|东邻到家系统|上门服务系统开发流程

上门服务小程序的开发流程是一个复杂且精细的过程&#xff0c;涉及到需求分析、设计规划、开发实施、测试验收以及上线运营等多个环节。下面将详细介绍上门服务小程序的开发流程&#xff0c;帮助读者全面了解并掌握其中的关键步骤。 一、需求分析 在开发上门服务小程序之前&am…

API攻击呈指数级增长,如何保障API安全?

从远程医疗、共享汽车到在线银行&#xff0c;实时API是构建数字业务的基础。然而&#xff0c;目前超过90%的基于Web的网络攻击都以API端点为目标&#xff0c;试图利用更新且较少为人所知的漏洞&#xff0c;而这些漏洞通常是由安全团队未主动监控的API所暴露&#xff0c;致使API…

24款奔驰GLE350升级原厂环视全景360影像 抬头显示HUD

奔驰GLE350原厂360全景影像的清晰度通常取决于车辆的具体型号和年份&#xff0c;以及安装的摄像头和显示屏质量。一般来说&#xff0c;原厂360全景影像系统会提供高清的影像&#xff0c;让驾驶者能够清晰地看到车辆周围的环境&#xff0c;帮助进行停车和转弯等操作抬头显示&…

AOP编程

AOP编程 AOP&#xff0c;面向切面编程&#xff0c;一种编程范式&#xff0c;指导开发者如何组织程序结构。 OOP&#xff0c;面向对象编程&#xff0c;一种编程思想。 AOP&#xff0c;提供了一种机制,可以将一些横切系统中多个模块的共同逻辑(如日志记录、事务管理、安全控制等…

WordPress搭建流程

1. 简介 WordPress 是一个 PHP 编写的网站制作平台。WordPress 本身免费,并且拥有众多的主题可以使用,适合用于搭建个人博客、公司官网、独立站等。 2. 环境准备 2.1 WordPress 下载 WordPress 可以在 Worpress中文官网 下载(如果后续要将后台调成中文的话,一定要从中文…

定时器

文章目录 11.11.21.31.41.5 22.12.2 基本定时器 框图2.32.42.4.12.4.22.4.32.4.42.4.52.4.6 2.5 定时器 溢出时间计算方法2.6 定时器 中断 实验配置步骤2.72.7.12.7.2 和42.7.32.7.52.7.6 33.13.23.2.1 时钟源3.2.23.2.43.2.6 3.33.43.4.13.4.23.4.33.4.43.4.53.4.5.13.4.5.23.…