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

news2024/11/28 10:51:18

前言

在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 + num2
        print(num)
    return inner

f = 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:

image.png

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

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

  1. 函数工厂(Function Factory):通过闭包可以创建一系列相似的函数,每个函数有不同的初始状态。
  2. 回调函数(Callback Functions):将函数作为参数传递,使得函数能够在未来的某个时刻被调用。
  3. 装饰器(Decorator):闭包是实现装饰器的基础,通过装饰器可以在不修改原函数代码的情况下增强其功能。

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

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

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

相关文章

APT攻击是什么?如何进行防护

随着网络技术的飞速发展&#xff0c;APT&#xff08;Advanced Persistent Threat&#xff09;攻击已经成为网络安全领域的一个重大问题。APT攻击是一种高度复杂的网络攻击&#xff0c;其目标是长期潜伏并逐步深入到目标网络中&#xff0c;以窃取敏感信息、破坏关键基础设施或制…

MyBatis 的注解实现方法

MyBatis 的注解实现方法 MyBatis 的注解实现方法引入依赖添加配置创建表创建实体类创建mapper接口InsertDeleteSelectResults和ResultMap通过配置文件解决 UpdateOptions MyBatis 的注解实现方法 引入依赖 在springBoot项目中下载了EditStarters插件的,可以直接在配置文件处右…

幻兽帕鲁怎么选择服务器

想要部署属于自己的幻兽帕鲁&#xff0c;首先需要拥有一台服务器&#xff0c;服务器是幻兽帕鲁运行的基础。游戏所需的服务器取决于游戏的规模、用户数量和功能需求。以下是一些通常需要考虑的服务器要求&#xff1a; 计算性能&#xff1a;包括cpu、内存、硬盘&#xff0c;cpu…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextPicker组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之TextPicker组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、TextPicker组件 TextClock组件通过文本将当前系统时间显示在设备上。支持不…

C++基础语法学习笔记

C Tutorial 1.基础语法 C 应用&#xff1a;操作系统、图形用户界面和嵌入式系统 C和C区别&#xff1a;C支持类和对象 C语法 #include <iostream> using namespace std;int main(){cout << "hello world!";return 0; }int main () { cout << &q…

vue之elementUi的el-select同时获取value和label的两种方法

一、通过ref的形式&#xff08;推荐&#xff09; <template><div class"root"><el-selectref"optionRef"v-model"value"placeholder"请选择"style"width: 250px"><el-optionv-for"item in optio…

Kubernetes实战(二十三)-k8s event监控利器kube-eventer对接企微告警

1 背景 监控是保障系统稳定性的重要组成部分&#xff0c;在Kubernetes开源生态中&#xff0c;资源类的监控工具与组件监控比较多。 cAdvisor&#xff1a;kubelet内置的cAdvisor&#xff0c;监控容器资源&#xff0c;如容器cpu、内存&#xff1b;Kube-state-metrics&#xff1…

自动驾驶:Apollo如何塑造人类的未来出行

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言1. 什么是自定义指令&#xff1f;2. Apollo中的自定义指令2.1 查询中的自定…

JSON巨匠:FastJSON的序列化解析

Fastjson 简介 Fastjson 是一个 Java 库&#xff0c;可以将 Java 对象转换为 JSON 格式&#xff0c;当然它也可以将 JSON 字符串转换为 Java 对象。 Fastjson 可以操作任何 Java 对象&#xff0c;即使是一些预先存在的没有源码的对象。 Fastjson 源码地址&#xff1a;https://…

数据可视化 pycharts实现时间数据可视化

自用版 数据格式为&#xff1a; 运行效果为&#xff1a; from pyecharts import options as opts from pyecharts.charts import Polar, Page import csv filename "./hot-dog-places.csv" data_x [] data_y [] with open(filename) as f:reader csv.reade…

有向图查询所有环,非递归

图&#xff1a; 有向图查询所有环&#xff0c;非递归&#xff1a; import java.util.*;public class CycleTest {private final int V; // 顶点数private final List<List<Integer>> adjList; // 邻接表public CycleTest(int vertices) {this.V vertices;this.…

python基础——池

池的介绍&#xff1a; 提前创建进程池&#xff0c;防止创建的进程数量过多导致系统性能受到影响&#xff0c;在系统执行任务时&#xff0c;系统会使用池中已经创建进程/线程&#xff0c;从而防止资源的浪费&#xff0c;创建的进程/线程可以让多个进程使用&#xff0c;从而降低…

SW-LIMS实现化工企业危险化学品信息化管理

随着化工产业的不断发展,危险化学品的生产和使用在经济和社会发展中扮演着重要的角色。然而,危险化学品的安全隐患也同样日益突出,从危化品的生产到储存、运输和使用,如果控制不当,很容易造成安全事故,而一旦发生安全事故,不仅会造成巨大的经济损失,还将威胁到人类的生命健康与…

FFmpeg和Monibuka拉取rtsp(大华摄像头)视频流时未进行URLCode编码导致提示404等报错

场景 Monibucav4(开源流媒体服务器)在Windows上搭建rtmp服务器并实现拉取rtsp视频流以及转换flv播放&#xff1a; Monibucav4(开源流媒体服务器)在Windows上搭建rtmp服务器并实现拉取rtsp视频流以及转换flv播放_monibuca 搭建流媒体服务-CSDN博客 Nginx搭建RTMP服务器FFmpeg…

C++引用、内联函数、auto关键字介绍以及C++中无法使用NULL的原因

文章目录 一、引用1.1 引用概念1.2 引用特性1.3 常引用1.4 使用场景1.4.1 做参数1.4.2做返回值 1.5 引用和指针的区别1.6 小结一下 二、内联函数2.1 内联的概念2.2 内联的特性2.3 【面试题】 三、auto关键字(C11)3.1 类型别名思考3.2 auto简介 四、auto的使用细则4.1 基于范围的…

Aloudata 近期荣誉盘点!接连斩获技术创新、案例实践、投资价值等权威认可

近期&#xff0c;Aloudata 凭借持续的技术积累、丰富的产品与解决方案以及多样场景下的最佳实践案例&#xff0c;在数据智能技术创新、案例实践、投资价值等领域全面开花&#xff0c;接连荣获&#xff1a; 2023 金猿榜「大数据产业年度最具投资价值」企业&#xff0c;并携手首…

APP开发者对接穿山甲广告联盟,有哪些特点?收益如何?

穿山甲平台作为巨量引擎旗下的第三方广告变现平台&#xff0c;在行业内始终处于领先地位&#xff0c;是不少开发者首选的对接平台。 通过穿山甲广告GroMore的Bidding竞价能力&#xff0c;不断提升自身的变现效率&#xff0c;新手可直接上手&#xff0c;避免繁琐调优流程&#…

PVE报错处理:kvm [2205]: vcpu0 ignored RDMSR: 0x1b8

PVE使用过程中如果遇到&#xff1a;kvm [2205]: vcpu0 ignored RDMSR: 0x1b8 报错信息处理方法 vim /etc/modprobe.d/kvm.conf "options kvm ignore_msrsY"&#xff0c;这里在msrsY后面加一个空格&#xff0c;然后粘贴report_ignored_msrsN&#xff0c;使其变成 op…

如何在微信搭建私域流量池?

A: ①给客户打标签 添加标签&#xff0c;多维度构建用户画像&#xff0c;精准发送消息。 ②群发信息 选择自定义时间&#xff0c;上传内容 (支持文字&#xff0c;图片) &#xff0c;一键群发 。 ③建立专属素材库 将常用的话术、图片与文件录入至素材库&#xff0c;员工可随…

微信小程序(基本操作)

概念&#xff1a; 小程序&#xff1a;就是小程序&#xff0c;mini program。现在市面上有微信小程序&#xff0c;百度智能小程序等等。 微信小程序&#xff0c;简称小程序&#xff0c;英文名Mini Program&#xff0c;是一种不需要下载安装即可使用的应用&#xff0c;它实现了…