Python之函数高级:一篇文章彻底搞懂什么是“闭包”
引言在编程中有一个让一些新手望而却步的概念——“闭包”。一方面, 闭包的定义以及作用机制着实略微有那么点复杂, 另一方面, 这个概念好像更倾向于数学、理论的范畴, 对于新手而言, 好像并没有太多的应用场景。不管怎样, 因由前面已阐述过的, 像是函数对象相关, 函数具备一等公民属性这件事还有高阶函数部分, 以及针对函数对象内部细节展开的深入探究等种种情况。我坚信去领会并熟练掌握“闭包”所涵盖的概念以及运用方式, 会朝着更为简易的方向发展, 这属于那种“顺理成章、自然而然就达成”的状况。本文的主要内容有1、探究“闭包”概念背后的本质2、一个闭包实例3、闭包的作用机制探究“闭包”概念背后的本质我们在前面的文章里, 曾提到编程学习之中的两大核心, 也就是“数据的表达”以及“数据的处理”, 那也能够表示成“数据结构”还有“算法”, 实际上, 这是一种极其简单的表达。从更加完整的角度去看, 每一个程序更为完整的构成, 都必然要有以下几个部分:1、输入数据的集合2、内部状态的集合3、计算规则的集合4、输出数据的集合这实际上同样是计算机科学背后那个图灵机的一种抽象, 从这个抽象层面来讲, 要是去看平常的编程语言里的函数, 我们能够发觉, 好像是图灵机的一个删减版本, 被删减的部分乃是“内部状态的集合”, 也就是说呀, 纯粹的函数是更着重于计算规则, 而不存在内部状态的那般的图灵机。然而, 存在某些时段, 我们的确必要内部状态, 鉴于内部状态各异, 对相同输入而言, 函数会给出不同输出。便是这样, “闭包”的概念出现了, 闭包能够大致被理解成“存在内部状态的函数”, 它是一种组合, 是一个函数跟与其相关的上下文环境状态的组合了。像这样去看的话, 闭包实际上就是一个单纯简省的物体, 该种物体仅仅拥有一项办法。反过来进行观察, 对象能够被视作是几个有着共享内部状况的闭包, 这样的一种说法同样不存在不合理之处, 是能够站得住脚的。故而, 闭包以及对象, 存有这样一种关系, 即看似是两个不同的概念, 实则又紧密相连, 从本质层面来讲, 它们就是同一个事物。依据此情况, 我们能够再进一步推导得出, 函数式编程跟面向对象编程, 在底层的基础层面上同样是属于一致的这一最终结论。要是处于别的函数式编程语言里面, 领会函数, 明白闭包, 理解对象好像还有些繁杂。然而, 要是我们将关注点汇聚到中去看, 因“一切皆对象”这个处于底层的“一”的存有, 在中的函数属于对象, 其自身同样是具备状态也就是属性的。那么, 于中好像我们又无需严格去区分啥是函数、啥是闭包了。因为在中的函数皆是对象, 都存有状态, 有状态的函数便是闭包, 所以在中一切函数似乎也皆是闭包了。的确没错, 上文提及的仅仅是依据底层观念而开展的某些推导罢了。于真实的编程语法层面而言, 平常的函数与闭包存在微微的差异。关联上一篇文章里头, 针对函数对象内里构成的探寻, 我们能够获取如下的论断:1、中的函数全都是对象, 因而, 从宽泛的意义来讲, 中的函数都能够是具备状态的函数。2、中的函数状态就是其定义执行的上下文环境。3、中的普通函数, 它的内部状态, 即其定义所在的全局命名空间, 此状态存在于函数对象内, 能够借助属性予以读写。4、里边的特殊函数对象, 专门指的是“闭包”, 它的内部状态, 除了属性对应的全局命名空间之外, 还有一个属性存储的, 是“闭包”所独有的内部状态。暂且中断对于概念的阐述, 只要存有一定理念性质的感知就行, 之后, 我们借助实际的代码去进一步展现这些概念。一个闭包实例给定一个带初始值的累加器的实现作为例子, 分别去看普通函数的使用情况, 并且去看闭包的使用情况, 进而对闭包的特点展开分析, 同时对闭包在特定场景里的优势所在进行比较。在真正使用闭包之前我们先看一下普通的有状态的函数的使用首先定义一个模块m1.pytotal 20def acc(step):totaltotal step然后我们在入口文件中导入m1模块进行函数调用m1print(f初始值为{m1.total})print(f函数内部状态{m1.acc.})m1.acc(5)print(f加5之后变为{m1.total})print(f函数内部状态{m1.acc.})m1.acc(10)以格式化方式输出, 输出内容为: 又加了10之后变为: 加上变量m1中的total属性的值。print(f函数内部状态{m1.acc.})执行结果来看执行结果, 中所定义的平常函数的确是存有状态的, 并且达成了累加器的成效。但是, 我们也应当认识到, 普通函数的状态, 从本质上来看, 并非仅仅归属于函数自身, 而是与函数所属模块里的所有函数、代码块共同分享的模块自身的全局命名空间。所以, 这个状态明显是欠缺安全性的, 毕竟全局变量里所贮存的状态, 其被更改的渠道颇为多样。除此之外在于, 因状态共享致使的不安全存在着, 我们是没有办法去达成多个不一样状态的累加器能够同时存在的这种情况的。下面我们通过闭包实现这个累加器的需求def acc(total20):def inner(step):totaltotal steptotalinneracc1 acc(0)print(acc1.)print(f初始状态{acc1..})print(f加10之后变为{acc1(10)})print(f加10之后变为{acc1(100)})acc2 acc(100)print(acc2.)print(f初始状态{acc2..})print(f加10之后变为{acc2(10)})print(f加10之后变为{acc2(100)})print(acc1)print(acc2)执行结果分析执行结果可知, 这般“闭包”的形式实实在在达成了各异累加器对象的同时存在, 闭包所特有的内在状态被存储于函数对象的属性里面。闭包的作用机制我们现粗略给出一个“闭包”的定义所谓“闭包”, 是指在嵌套定义的函数里, 有一个内部函数引用了外部函数中的局部变量, 而且该外部函数的作用域已然结束, 这种内部函数和它所应用的外部函数的变量一同构成了闭包。闭包可以保存和访问它创建时的环境即使在外部函数结束之后。前面曾经提及过, 高阶函数存在两个条件, 只要满足其中一个便属于高阶函数也就是说, 要么把函数当作参数来进行传递, 要么返回一个函数对象。闭包明显是满足第二个条件的高阶函数。下面我们来简单概括一下创建一个闭包所需要的条件1、存在嵌套定义的函数。2、内部函数引用了其外部函数中的变量。3、有一个外部函数存在, 它返回了这样一个对象, 此对象是内部函数对象, 要注意, 这里返回的是函数对象, 并非是内部函数完成调用之后所产生的结果, 是有区别的。同时满足上面的3个条件就可以创建闭包了。从本质的角度来讲, 每一个函数都存在着自身所特有的局部具有限定范围的命名空间, 同时也有着归其所属的全局性的命名空间。一旦, 当闭包得以创建的条件达到了满足的状态时, 就必然会生成一个全新的命名空间, 也就是被称作闭包命名空间的那部分空间。只要是在嵌套函数定义里, 内部函数引用了外部函数那一块儿的局部变量, 这样子才会被添加到闭包命名空间范围中, 这是一定要做到的, 对此是严谨规定的, 有着明确要求的。再次看一下定义能瞧见, 函数对象里, 指向闭包命名空间的属性, 是个元组, 其元素类型, 为_Cell, 而那_Cell对象, 是有属性的。所以, 在上面代码里, 对闭包命名空间中所存储的内部状态进行访问, 是借助..得以实现的。此外, 倘若要 在内部函数作用域里, 尝试去修改外部函数当中定义的局部变量, 需知外部函数的形参同样是外部函数的局部变量, 那么就需要借助关键字来对变量展开声明, 不然的话就会被解释器认定为是在定义一个内部函数里的局部变量, 并且还会给其赋上初始值。在前面函数的局部作用域里, 当我们尝试去修改全局变量时, 碰到过类似关键字声明的情况, 也就是关键字。从和这两个被称作关键字的玩意儿当中, 同样是能够瞧得出来闭包作用域那尴尬之处的, 因为并没有使用关键字, 所以并非全局命名空间, 也就是并非local 它可不是局部命名空间。处于全局命名空间以及局部命名空间夹缝中间的那一部分, 暂且权且把它叫作闭包命名空间好了。从名字解析所依照的LEGB规则来看, 能发现, Llocal与G之间的E, 此前未曾展开提及, 实际上就是这个闭包命名空间, 其中的名字解析契合就近原则, 内部的能够覆盖外部的。实际上, 于我而言, 没必要专门对“闭包”的概念予以着重强调, 只要可以明白函数自身身为对象, 已然自然而然地拥有内部状态这样的特性。明白了这些底层的作用运行机制, 就已然充分了。总结本文对闭包的定义予以了详尽阐释, 对其本质也进行了细致说明, 还针对函数、闭包、对象这几个范畴的区别与联系作出了解释, 与此同时, 介绍了闭包得以成立的条件以及与之相关的内部状态的存储机制。在对闭包有了理解的基础之上, 又一次回顾了LEGB规则。感谢您的拨冗阅读希望对您理解中的闭包能有所帮助。

相关新闻

如何通过Sunshine自托管游戏串流服务器实现跨平台游戏体验

如何通过Sunshine自托管游戏串流服务器实现跨平台游戏体验

如何通过Sunshine自托管游戏串流服务器实现跨平台游戏体验 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否曾想过将高性能PC上的游戏无缝串流到平板、手机或客厅电视上&…

2026/8/5 0:07:45 阅读更多 →
当围棋遇见AI:我与LizzieYzy的七天探索之旅

当围棋遇见AI:我与LizzieYzy的七天探索之旅

当围棋遇见AI:我与LizzieYzy的七天探索之旅 【免费下载链接】lizzieyzy LizzieYzy - GUI for Game of Go 项目地址: https://gitcode.com/gh_mirrors/li/lizzieyzy "围棋不是关于赢棋的游戏,而是关于理解的艺术。"——但理解从何而来&am…

2026/8/5 0:07:45 阅读更多 →
SolidWorks齿轮阵列与修剪技术实战指南

SolidWorks齿轮阵列与修剪技术实战指南

1. SolidWorks齿轮阵列与修剪的核心价值齿轮作为机械传动系统的核心部件,其建模精度直接影响运动仿真和加工质量。传统逐个绘制齿轮齿形的方法不仅效率低下,更难以保证齿距均匀性。我在汽车变速箱设计项目中实测发现,使用图形阵列配合修剪技术…

2026/8/5 0:07:45 阅读更多 →

最新新闻

2026年宁夏能做智慧燃气安全监测管理系统的服务商有哪些?

2026年宁夏能做智慧燃气安全监测管理系统的服务商有哪些?

西北干旱区的燃气安全监测有其独特底数——管网增速快、气候严苛。宁夏城镇燃气管网以银川为中心向石嘴山、吴忠、中卫、固原辐射,城镇化提速和"煤改气"推进带来管线里程快速增长,新老管网交织的接口管理、材质差异问题正成为安全监管的新焦点…

2026/8/5 0:50:19 阅读更多 →
蓝速科技一体双面 AI 双屏翻译机商务采购避坑指南

蓝速科技一体双面 AI 双屏翻译机商务采购避坑指南

在跨国商务洽谈或涉外接待现场,语言障碍往往是阻碍沟通效率的第一道墙。很多行政采购或项目负责人在选型时,容易陷入一个误区:直接照搬消费级市场的热门手持翻译机。然而,当场景从“个人出差”切换到“会议室谈判”或“前台接待”…

2026/8/5 0:50:19 阅读更多 →
蓝速科技 AI 数字人一体机选购指南:大厂生态与高性价比方案深度评测

蓝速科技 AI 数字人一体机选购指南:大厂生态与高性价比方案深度评测

在规划展厅导览或酒店迎宾项目时,很多负责人往往容易陷入一个误区:盲目追求头部大厂的“全生态”方案,却忽略了实际场景中对成本与稳定性的真实需求。对于单点位的政企服务窗口、中小型文旅展厅或是商业门店而言,动辄数十万的系统…

2026/8/5 0:50:19 阅读更多 →
抖音无水印视频下载器终极指南:如何快速保存高清视频内容

抖音无水印视频下载器终极指南:如何快速保存高清视频内容

抖音无水印视频下载器终极指南:如何快速保存高清视频内容 【免费下载链接】douyin_downloader 抖音短视频无水印下载 win编译版本下载:https://www.lanzous.com/i9za5od 项目地址: https://gitcode.com/gh_mirrors/dou/douyin_downloader 想要保存…

2026/8/5 0:50:19 阅读更多 →
NsEmuTools:告别繁琐配置,一站式管理任天堂Switch模拟器

NsEmuTools:告别繁琐配置,一站式管理任天堂Switch模拟器

NsEmuTools:告别繁琐配置,一站式管理任天堂Switch模拟器 【免费下载链接】ns-emu-tools 一个用于安装/更新 NS 模拟器的工具 项目地址: https://gitcode.com/gh_mirrors/ns/ns-emu-tools 还在为NS模拟器的复杂配置而烦恼吗?每次安装新…

2026/8/5 0:50:19 阅读更多 →
3步快速掌握League Akari:英雄联盟终极效率工具完整指南

3步快速掌握League Akari:英雄联盟终极效率工具完整指南

3步快速掌握League Akari:英雄联盟终极效率工具完整指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否曾在英雄选择阶段犹…

2026/8/5 0:49:19 阅读更多 →

日新闻

Java缓存框架:JetCache

Java缓存框架:JetCache

TOC 一、简介 JetCache 是一个 Java 缓存抽象框架,为不同的缓存解决方案提供了统一的使用方式。 它提供的注解比 Spring Cache 更加强大。 JetCache 的注解支持原生 TTL、两级缓存以及在分布式环境中的自动刷新功能,同时你也可以通过代码直接操作 Cach…

2026/8/5 0:00:43 阅读更多 →
AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

需求:通孔焊盘 十字花;过孔 Via 实心直连;贴片焊盘按需设置 AD 测试版本AD24 很多工程师踩坑:全部统一十字,导致接地过孔阻抗高、大电流发热! 一、快捷键打开规则 PCB 界面按下:D R 展开…

2026/8/5 0:00:43 阅读更多 →
AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

更多请点击: https://kaifayun.com 第一章:AI生成素描效果 AI生成素描效果是计算机视觉与风格迁移技术融合的典型应用,其核心在于将彩色照片或RGB图像转换为具有手绘质感、明暗对比强烈、边缘清晰的单色素描图像。该过程通常依赖于深度学习模…

2026/8/5 0:00:43 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/4 13:24:41 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/4 11:41:39 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/4 5:26:40 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/4 13:38:24 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/4 11:09:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/4 13:38:40 阅读更多 →