Python之函数【三】(高阶函数和闭包)

news2024/12/21 19:02:37

文章目录

  • 前言
  • 一、高阶函数
  • 二、闭包(也称之为:闭包函数)
    • 1、浅谈闭包函数        
      • 1.1、划重点
      • 1.2、注意点
    • 2、怎么判断是不是闭包函数呢?
      • 2.1、那接下来,我们就细细的拆开解释
      • 2.2、对于这个作用域,在JavaScript中的解释
      • 2.3、闭包函数的相关元素查看
        • ​​​​​​​​​​​​​​2.3.1、闭包函数的__code__属性(编译后的函数定义体)中保存着闭包函数的局部变量和自由变量的名称
        • 2.3.2、自由变量的值查看
  • 三、nonlocal关键字的使用​​​​​​​
  • 总结


前言

记录一下自己对高级函数和闭包函数的理解,以及着重点和注意点的分析和讲解。这个章节的基础是为了理解装饰器。


一、高阶函数

什么叫高阶函数呢?

定义:如果一个函数的参数,是另外一个或几个函数,那么这个函数就是高阶函数。

怎么理解呢?通俗点说:就是一个函数中要传进来的参数就是一个函数。不是具体的字段值。

举例:

 注意在这里:在fun2函数里面要使用传进来的函数,那么里面必须是一个函数的完整格式,不能只是一个函数名称。

 

 当传入多个函数作为参数时:

二、闭包(也称之为:闭包函数)

1、浅谈闭包函数

闭包这个词有点怪,其实就是一类具体一些明显特点的函数。也可以叫做:闭包函数。

对于闭包,我们先来讲闭包函数的三个特点。

(1)闭包函数内嵌套有其它函数

(2)内嵌函数引用了外层函数的变量

(3)外层函数的返回值是嵌套函数的函数名字

1.1、划重点:

第一点:闭包函数内嵌套有其它函数。也就是说:定义了一个函数fun1,那么在函数fun1中还可以定义一个函数fun2

第二点:内嵌函数引用了外层函数的变量。也就是说:在函数fun1中定义了一个变量a,现在在函数fun2中引用了fun1的变量a。

第三点:外层函数的返回值是嵌套函数的函数名字。也就是说,fun1这个外层函数的返回值,是fun2这个函数的名字。注意是名字。

 1.2、注意点:

(1)如果要使用这种闭包函数,那么就要先使用一个变量去接收这个函数的返回值。

(2)这个返回值就相当于是内层函数。

我们接下来细化理解一下:

依据上面的例子:a1去接收了fun1()这个函数的返回值。那么a1就等于fun2;我们使用a1就等同于使用fun2()这个函数。

如果:当函数fun1()里面传值,但是fun2()里面不传值时,调用函数的方式有些变化:

2、怎么判断是不是闭包函数呢?

 使用内层函数.__closure__方法来判断是否是闭包。如果返回的是一个cell对象,那么就是闭包函数。如果返回None就不是闭包函数。

注意:这里一定是内层函数去调用这个__closure__方法,内层函数也就是外层函数的返回值。

总结:我们可以看到闭包函数的一个特点就是,嵌套函数。另一个特点是外层函数的变量作用域在内层函数中使用。

专业术语的定义是:闭包是一种函数,一种延伸了变量作用域的函数,它会保留定义函数时变量的绑定,当定义变量的作用域不可以用了,那些绑定仍然可以被调用。

2.1、那接下来,我们就细细的拆开解释:

(1)闭包是一种函数。也就是说,闭包是个名称,全称闭包的名字也叫闭包函数。

(2)延伸了变量作用域的函数。也就是说,本来变量的作用域在函数fun1,现在把在函数fun1的变量拿到函数fun2中使用,那么这种行为就叫做延伸了变量作用域。

(3)当定义变量的作用域不可以用了,那些绑定仍然可以被调用。也就是说,当函数fun1执行完毕了(这里解释一下什么叫做执行完毕:也就是说fun1运行完,那么fun1的作用域也就跟着运行完)。那么在函数fun2中使用函数fun1的变量这种关系,是不会消除(也就是说:fun1函数运行完了,我fun2函数还是能够照样使用你fun1的作用域,对fun2函数产生不了影响)。如果消除了那就不是闭包函数了。

通过对JavaScript语言对比的新解释:那就是在一个函数里边再定义一个函数。这个内部函数一直保持有对外部函数中作用域的访问(小盒子可以一直访问大盒子但大盒子不能访问小盒子)。

对应第三点:

我们类比学习不是闭包函数的作用域:

 这里的作用域list_1只能在函数fun1中被应用。

2.2、对于这个作用域,在JavaScript中的解释:

 作用继承

所谓的作用域继承,就像是儿子可以继承父亲的财产一样。比如我这里有一个大的盒子作为一个父级的作用域,然后在这个大的盒子里边放一个小的盒子,作为子作用域。我们规定可以在小盒子中获取到大盒子中的东西,大盒子不能获取小盒子里的东西就称为作用域继承。

在 JS 中,道理是一样的,在一个函数里边我们再声明一个函数,内部函数可以访问外部函数作用域的变量,而外部的函数不能获取到内部函数的作用域变量。

参考博主文章:闭包:什么是闭包、闭包的作用、闭包的解决_BUG使我疯狂的博客-CSDN博客

2.3、闭包函数的相关元素查看

2.3.1、闭包函数的__code__属性(编译后的函数定义体)中保存着闭包函数的局部变量和自由变量的名称,如下:

co_varnames:查看局部变量名称

co_freevars:查看自由变量名称

顾名思义就知道这两个函数的意思了。

 2.3.2、自由变量的值查看

自由变量的值是保存在__closure__[freevars].cell_contents 属性中的

 

三、nonlocal关键字的使用

3.1、首先我们先明白一个场景。我们在一个普通函数中把局部变量变成全局变量,使用的关键字是global。

 

3.2、那么在闭包函数里面可以使用global关键字的形式把局部变量改变成全局变量?

答案是:不行

(1)使用global关键字修改外层函数的变量

 

(2)使用nonlocal关键字修改外层函数的变量

 参考文章:Python之闭包_python 装饰器_搬砖,攒路费的博客-CSDN博客


总结

闭包函数一定满足三个特征,但是满足这三个特征的函数不一定是闭包函数。因为:里面的关键字申明的变量,我们上面的例子就很好的解释这一点了。

说通俗一点:人会吃饭,但吃饭的不一定是人。

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

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

相关文章

【MySQL数据库基础】

MySQL数据库基础 1. 数据库的操作1.1 显示当前的数据库1.2 创建数据库1.3 使用数据库1.4 删除数据库 2. 常用数据类型2.1整数(xxxint)2.2日期时间类型2.3字符串型 3. 表的操作3.1 查看表结构3.2 创建表3.3 删除表 1. 数据库的操作 1.1 显示当前的数据库…

Es索引中时间字段是字符串Range查询的正确姿势

文章目录 [toc] 1. 问题2. Es索引的mapping模式2.1 dynamic动态宽松模式(动态映射)2.2 strict严格模式(静态映射) 3. text类型和keyword类型的区别3.1 text类型3.2 keyword类型 4.正确姿势5. 总结 1. 问题 由于之前搞了一个使用fl…

230616安装SqlServer2017Express

230616安装SqlServer2017Express 下载地址 选择语言 Microsoft SQL Server 2017 Express 下载地址: 简体中文 感谢下载 Microsoft SQL Server 2017 Express 我将下载的文件的名称加上了SHA256值, 一长串 是一个 .exe 的自解压文件, 双击后,默认解压到同根文件夹\同名文件夹下,…

那些可以当源码学习的优质开源项目分享

本篇收集的是自己平时逛 Github 发现的一些优质的开源项目,为什么收集它? 借助优质的开源项目,我们不仅可以拿来二次开发快速实现想要的功能,而且还可以学习里面优秀的代码,提高我们的编程能力。读(拆解&am…

vue实现elementUI table表格树形结构-使用懒加载时-解决子节点增删改后,不刷新子节点数据问题

问题发现 在使用element-ui的table组件时,使用树形结构,并使用了懒加载,可出现了一个问题,在对当前节点添加一个子节点数据,或删除一个子节点数据时,当前节点的子节点数据并不自动刷新出来。element-ui官方…

景联文科技:一文详解关键点标注

关键点标注是计算机视觉领域的一种任务,指的是在图像或视频序列中标注出特定目标的关键点,这些关键点通常是目标的重要特征点或轮廓点,包括但不限于人体关节、面部特征点、车辆零部件等。通过对关键点的标注,可以为后续的目标跟踪…

19. 算法之分治算法

1. 概念 分治算法(divide and conquer)的核心思想其实就是四个字,分而治之 ,也就是将原问题划分成n个规模较小,并且结构与原问题相似的子问题,递归地解决这些子问题,然后再合并其结果&#xff…

微信小程序开发(1)

10分钟入门 - 微信小程序开发 微信小程序详细教程 小程序简介 小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验。 小程序技术发展史 WeixinJSBridge.invoke(imagePreview, { 2. current: http://i…

大数据之路书摘:走近大数据——从阿里巴巴学习大数据系统体系架构

文章目录 1.数据采集层2.数据计算层3.数据服务层4.数据应用层 在大数据时代,人们比以往任何时候更能收集到更丰富的数据。但是如果不能对这些数据进行有序、有结构地分类组织和存储,如果不能有效利用并发掘它,继而产生价值,那么它…

SNMP软件及性能监控

SNMP(Simple Network Management Protocol)是一种用于网络管理的协议。通过SNMP,我们可以监测和管理网络设备、服务器等重要设备的性能和状况,从而确保网络的正常运行。但在开始使用之前,需要进行配置,以便…

计算机未来五年最吃香的4个职位,对女生超级友好!

今年计算机毕业的学弟学妹对于找工作感觉到非常焦虑,不知道该哪个方向就业才有出路。很多同学感觉在学校好像什么都学了,又好像什么都没学到,先不说企业会不会招,自己就连投简历的勇气都没有,生怕大把的简历投出去就石…

怎么买美股?有哪些美股购买常见问题?

美股市场是全球最大的股票市场,也是全球最受投资者关注的市场之一。许多投资者都想参与其中,但不知道如何买美股。上文中已经扩列了美股购买的基本规则,继续为大家分享美股购买常见问题的相关知识要点。更深入的认识美股交易。 美股购买常见问…

组装电子产品,如何避免SMT虚焊?

组装电子产品的工厂,主要包括两条生产线:SMT表面组装和DIP插件组装。SMT是把电子元件通过设备,贴到PCB线路板上面,然后通过炉子(一般是指回流焊炉)加热,把元件通过锡膏焊接固定到PCB板上&#x…

【C++】STL的deque容器

目录 3.1deque构造函数 3.2deque赋值操作 3.3deque大小操作 3.4deque插入 3.5deque删除 3.6deque数据存取 3.7deque排序操作 deque(双端队列)是double-ended queue 的一个不规则缩写。deque是具有动态大小的序列容器,可以在两端&#…

遗传算法[GA]

遗传算法 遗传算法 (Genetic Algorithm,GA) 是模拟生物在自然环境中的遗传和进化的过程而形成的自适应 全局优化搜索算法。 遗传算法借鉴了达尔文的进化论和孟德尔的遗传学说。其本质是一种并行、高效、全局搜索的方法, 它能在搜索过程中自动获取和积累…

centos直接部署express

centos直接部署express 以下是在CentOS上部署Express应用程序的一般步骤: 1.安装Node.js 在CentOS系统上安装Node.js。可以使用以下命令安装Node.js: sudo yum install nodejs2.安装npm 安装完Node.js后,还需要安装npm(Node.…

数据库原理与应用第7章作业

数据库原理与应用第7章作业 一. 单选题(共10题,40分)二. 填空题(共3题,15分)三. 简答题(共1题,15分)四. 论述题(共2题,30分) 一. 单选…

测试“背锅侠”?软件测试人究竟背了多少锅?我不再背锅...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 实际上&#xff0…

多线程并发的一些常见的使用规范

目录 1. 多线程并发使用规范 1.1 指定线程名称 2. 尽量使用线程池 3.不允许使用Executors 4. 正确停止线程 5. 编写可停止的Runnable 6 . Runnable中必须捕获一切异常 7. 可考虑使用ThreadLocal 8. 缩短锁 9. 选择分离锁,分散锁甚至无锁的数据结构 10. 推…

【C/C++】标准库相关题型(一)

文章目录 1. vector底层实现原理1.1 类构成1.2 构造函数1.3 插入元素1.4 删除元素1.5 读取元素1.6 修改元素1.7 释放空间 2. vector内存增长机制2.1 特点2.2 内存增长特性2.3 内存增长过程2.4 内存清理2.5 注意事项 3. vector中reserve和resize的区别3.1 共同点3.2 区别3.3 应用…