一文带你彻底搞懂 Python 编程进阶之闭包

什么是闭包:在函数嵌套的情况下,内部的函数使用外部函数中的变量,并且外部函数返回了内部函数,我们将这个内部函数称之为闭包。

闭包是实现装饰器的基础,通过装饰器可以在不修改原函数代码的情况下增强其功能。

在Python编程语言中,闭包是强大而灵活的语法,它为开发者提供了一种优雅而高效的方式来处理函数和代码结构。作为自动化测试和测试开发同学,弄懂它的作用及工作原理很有必要,面试中提及到的概率非常之大。

关于函数名的本质 

在介绍闭包之前首先我们看一段简单的Python代码:


def func():print("hello lemon")
# 1、调用func函数
func()
# 2、打印函数
print(func)

上述案例中,定义了func函数,在下面通过函数名()进行调用,其结果是"hello lemon",这个大家都知道,如果使用print(func),其结果是多少呢?如下所示:

hello lemon
<function func at 0x00000276301841F0>

我们可以发现,print(func)并不是None,而是对应的一段内存地址。

通过上述的小实验我们可以得出来一个结论:

在Python中,函数名存放的其实就是函数所在的内存地址,通过函数名()的方式本质上就是执行函数所在内存地址中的代码。

理解了函数名的作用之后,接下来我们看看闭包到底是个什么玩意。

闭包

我们将上述的案例升个级,代码如下所示:

def func(num1):def inner(num2):num = num1 + num2print(num)return innerf = func(10)
f(20)

这个案例中我们使用了函数嵌套函数(也就是在定义函数的内部还有另外一个函数),func函数我们称之为外部函数,inner函数我们称之为内部函数。

这里注意

  • 这两个函数之间是有联系的,在inner内部函数中我们使用了func外部函数的变量num1

  • return inner这段代码是在func外部函数中将inner函数返回

代码输出结果:30

我们先来理解f = func(10)这段代码:参数10将会传递给inner函数使用,由于func函数内部会使用return innerinner函数返回,结合上述我们讲到的函数名本质,这里其实相当于是将inner函数的地址返回,所以这里的f其实代表的就是inner内部函数。

所以f(20)其实就是调用inner函数,此时num1变量存的是10,num2存的是20,两者相加所以最终结果为30。

结合上述的案例我们再来看下闭包的定义:

在函数嵌套的情况下,内部的函数使用外部函数中的变量,并且外部函数返回了内部函数,我们将这个内部函数称之为闭包。

闭包需要满足的几个条件:

  1. 需要有外部函数和内部函数的嵌套 ==> 对应func和inner函数

  2. 内部的函数使用外部函数中的变量 ==> inner函数中使用func函数的变量num1

  3. 外部函数中返回了内部函数 ==>return inner

闭包有什么用呢?

在上数的案例中,如果我们再使用f(30)f(40)去进行调用的话,会发现对应的结果为40和50:

图片

也就是说,外部函数func中的变量num1不会随着函数调用完就销毁,而是一直有效。变量num1的值在闭包函数inner中被保持了下来。

闭包的特性使得函数不仅仅是一段独立的代码,还可以携带一些状态。这种状态对于函数的灵活性和可重用性非常有用。常见的使用场景如:

  1. 函数工厂(Function Factory):通过闭包可以创建一系列相似的函数,每个函数有不同的初始状态。

  2. 回调函数(Callback Functions):将函数作为参数传递,使得函数能够在未来的某个时刻被调用。

  3. 装饰器(Decorator):闭包是实现装饰器的基础,通过装饰器可以在不修改原函数代码的情况下增强其功能。

特别是装饰器,作为自动化测试人员一定不陌生,pytest测试框架就是利用装饰器的特性来实现特定的功能,比如通过@pytest.mark.parametrize装饰器能够实现数据驱动测试的功能,装饰器的本质其实就是闭包,所以在理解了闭包的基础上才能理解装饰器的原理,关于装饰器的使用可以关注后续的文章。

 

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

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

相关文章

【elasticsearch】搜索结果处理

搜索结果处理 排序 elasticsearch支持对搜索结果排序&#xff0c;默认是根据相关度算分&#xff08;_score&#xff09;来排序。可以排序字段类型有&#xff1a;keyword类型、数值类型、地理坐标类型、日期类型等。 GET /indexName/_search {"query":{"match_a…

C++多继承之菱形继承原理及解决方法

目录 1.单继承和多继承 2.菱形继承 3.虚继承解决菱形继承 3.1使用方法 3.2虚继承原理 4.继承和组合 1.单继承和多继承 一个子类只有一个父类称为单继承 一个子类有多个父类称为多继承 2.菱形继承 菱形继承是多继承的一种复杂的情况 这里会出现一个问题&#xff0c;Assi…

prometheus+grafana监控nginx的简单实现

1.编译安装NGINX 加入编译安装nginx-module-vts模块,目的是为了获取更多的监控数据(虚拟主机&#xff0c;upstream等) nginx下载 http://nginx.org/download/nginx-1.20.2.tar.gz nginx-module-vts下载 https://github.com/vozlt/nginx-module-vts/archive/refs/tags/v0.2…

谁是单身狗?——C语言刷题

创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 单身狗1 题述 在一个整型数组中&#xff0c;只有一个数字出现一次&#xff0c;其他数组都是成对出现的&#xff0c;请找出那个只出现一次的数字。 例如&#xff1a; 数组中有&#xff1a;1 2 3 4 5 1 2 3 4&a…

【Docker】docker常用命令

需要云服务器等云产品来学习Linux可以移步/-->腾讯云<--/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;新用户首次下单享超低折扣。 目录 一、镜像仓库架构图 二、docker仓库命令 1、登录仓库docker login 2、拉取镜像docker pull 3、推送镜像docker pus…

电子器件系列64:稳压二极管ZM4728A

C143062_稳压二极管_ZM4728A-GS08_规格书_WJ481159 稳压管可以用于信号线路的旁路&#xff0c;用于过滤高频信号&#xff1f; 这种电路叫做限幅电路 从集成电路Al的①脚输出信号通过Rl加到集成电路A2的①脚。当集成电路Al的①脚输出信号幅度没有超过VD1稳压值时&#xff0c;这…

【Python】Windows本地映射远程Linux服务器上的端口(解决jupyter notebook无法启动问题)

创作日志&#xff1a; 学习深度学习不想在本地破电脑上再安装各种软件&#xff0c;我就用实验室的服务器配置环境&#xff0c;启动jupyter notebook时脑子又瓦特了&#xff0c;在自己Windows电脑上打开服务器提供的网址&#xff0c;那肯定打不开啊&#xff0c;以前在其它电脑上…

轮盘类零件

轮盘类零件 轮盘类零件也是组成机器的常见零件&#xff0c;如法兰盘、轴承端盖、各种泵盖、齿轮、蜗轮、链轮、带轮、飞轮、手轮、离合器中的摩擦盘等。轮类零件主要传递运动及动力&#xff0c;如齿轮、蜗轮、链轮、带轮、飞轮、手轮等;盘盖类零件主要起支承、轴向定位或密…

Vue.js+SpringBoot开发超市商品管理系统

目录 一、摘要1.1 简介1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 超市区域模块2.3 超市货架模块2.4 商品类型模块2.5 商品档案模块 三、系统设计3.1 用例图3.2 时序图3.3 类图3.4 E-R图 四、系统实现4.1 登录4.2 注册4.3 主页4.4 超市区域管理4.5 超市货架管理4.6 商品类型…

JSTL标签

JSTL标签 一、什么是JSTL标签&#xff1a; 随着J2EE瘦客户机技术JavaServer Pages(JSP)在过去几年中的流行&#xff0c;开发人员已经创建了许多自定义的JSP标记库。虽然很多标记库是为实现不同目标的而编写的&#xff0c;但它们往往也对迭代、条件及其它通用操作都提供了类似…

Java常用设计模式

文章目录 代理模式代理模式的作用静态代理动态代理动态代理的两种方式 代理模式 代理模式&#xff1a;当我们要去访问一个目标类的时候&#xff0c;不是直接去访问这个目标类&#xff0c;而是去访问这个目标类的代理类&#xff0c;由这个代理类去调用目标类。也就是我们间接的…

【数据结构】图——最短路径

最短路径问题&#xff1a;从在带权有向图G中的某一顶点出发&#xff0c;找出一条通往另一顶点的最短路径&#xff0c;最短也就是沿路径各边的权值总和达到最小。 最短路径分为图中单源路径和多源路径。 本文会介绍Dijkstra和Bellman-Ford解决单源路径的问题 Floyd-Warshall解…

来看大厂如何设计运营后台系统的?

0 背景 重运营的应用。对于App里的顶导航、我的页面、弹窗等&#xff0c;需要根据模式、版本、平台、语言、渠道等不同的维度进行运营管理。随着业务快速发展&#xff0c;版本快速迭代&#xff0c;如何&#xff1a; 保持运营资源能够被高效、稳定和灵活地配置高效稳定的为新的…

【洛谷千题详解】P1031 均分纸牌

目录 题目描述 思路点拨 AC代码 题目描述 题目网址&#xff1a;[NOIP2002 提高组] 均分纸牌 - 洛谷 有 N 堆纸牌&#xff0c;编号分别为 1,2,……,N。每堆上有若干张&#xff0c;但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌&#xff0c;然后移动。 移牌规则为&a…

YOLO如何训练自己的模型

目录 步骤 一、打标签 二、数据集 三、跑train代码出模型 四、跑detect代码出结果 五、详细操作 步骤 一、打标签 &#xff08;1&#xff09;在终端 pip install labelimg &#xff08;2&#xff09;在终端输入labelimg打开 如何打标签&#xff1a; 推荐文章&#xf…

代码随想录算法训练营day27|39. 组合总和、40.组合总和II

39. 组合总和 如下树形结构如下&#xff1a; 选取第二个数字5之后&#xff0c;剩下的数字要从5、3中取数了&#xff0c;不能再取2了&#xff0c;负责组合就重复了&#xff0c;注意这一点&#xff0c;自己做的时候没想明白这一点 如果是一个集合来求组合的话&#xff0c;就需…

找游戏 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 小扇和小船今天又玩起来了数字游戏&#xff0c; 小船给小扇一个正整数 n&#xff08;1 ≤ n ≤ 1e9&#xff09;&#xff0c;小扇需要找到一个比 n 大的数字 m&a…

算法 给定N个整数序列{A1,A2,....,An}求所有子序列之和的最大值

今天 &#xff0c; 开始学习算法 &#xff0c; 以这个列子解释复杂度对算法的影响 #include <stdio.h> int main() { int i 0; int arr[8] { -1,2,-3,4,-4,7,8,9 }; int j 0; int k 0; int sum 0; int max_sum 0; for( i 0 ; i < …

c#中使用devexpress gridcontrol 获取排序后的gridview数据

//获取排序后的DataTable DataTable _dt lvwItems.GridControl.DataSource as DataTable; DataTable table _dt.Clone(); for (int i 0; i < lvwItems.RowCount; i) { if (lvwItems.IsGroupRow(i)) …

如何增加层次厚度?

Q 老师&#xff0c;我在做一个斧头武器&#xff0c;如何在平面上增加厚度和层次呢&#xff1f; A 选中这几个线&#xff0c;点连接就会出现中线&#xff0c;把中线稍作调整即可~