第13.2节 关于闭包

Python 闭包是啥? 读懂此文,远离“闭包”烦恼!! Python 闭包 阅读详情

一、 概念
闭包(Closure)又称词法闭包(Lexical Closure)或函数闭包(function closures),闭包与函数嵌套有关,在《第5.5节 函数递归、嵌套及样例》中老猿介绍了函数嵌套,函数中嵌套的函数称为嵌套函数、外层的函数称为封闭函数。闭包简单来说就是一个嵌套函数中引用了封闭函数定义的变量,并且该函数可以在其定义环境外即封闭函数外被执行。这样的嵌套函数我们称之为闭包。嵌套函数使用的封闭函数的变量称为自由变量。
在闭包的情况下,在调用封闭函数后,会将嵌套函数返回给调用方,调用结束后,封闭函数执行结束,其执行时的自由变量传递给了嵌套函数保存,而嵌套函数被调用方保存,意味着调用方获取了嵌套函数及其调用时自由变量的值,意味着嵌套函数与封闭函数脱离了关系独立存在。因此闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
要创建闭包,必须满足以下条件:
• 必须包含一个嵌套函数
• 嵌套函数必须引用封闭函数中定义的自由变量,在引用前需用nonlocal关键字进行声明
• 封闭函数的调用结果必须将嵌套函数作为其返回值

二、 闭包的好处

  1. 取代硬编码中的常量
    由于闭包中可以通过封闭函数的自由变量传递值给闭包函数,而闭包函数中该自由变量的值可以保持不变,这样可以不使用常量来实现,又具有灵活性,通过不同的闭包实例使用不同的自由变量值。
  2. 避免使用全局值,并提供某种形式的数据隐藏
    在闭包实例中自由变量可以在脱离封闭函数的情况下保持不变,从而取代了全局变量的作用。
  3. 实现面向对象
    闭包可以允许不同的实例实际执行存在差异,这样可以在不同类中调用同一封闭函数传递不同自由变量的值而实现不同的执行效果,这样调用方无需关注是通过哪个类进行调用,从而实现了一定程度的封装。

三、 案例

>>> def cal(op):
    def calop(op1,op2):
        nonlocal op
        if op=='+':return op1+op2
        elif op=='-':return op1-op2
        elif op=='*':return op1*op2
        elif op=='/':return op1/op2
        else: raise ValueError('运算符必须是+-*/中的一个')
    return calop

>>> add =cal('+')
>>> minus=cal('-')
>>> add(1,2)
3
>>> minus(1,2)
-1
>>>

四、 补充说明

  1. 所有函数对象都有一个 closure 属性,如果这个函数是一个闭包函数,那么会返回的是一个由 cell 对象组成的元组。cell 对象具有 cell_contents 属性,存储了闭包中的自由变量。这也解释了为什么局部变量在脱离函数之后,还可以在函数之外被访问,因为它存储在了闭包的 cell_contents 中;
  2. 闭包之所以又称为词法闭包,是因为自由变量的作用域在定义时确认了,而不是在执行时决定。这符合词法作用域(Lexical Scoping)的概念。词法作用域取决于源码,通过静态分析就能够确定,因此,词法作用域也叫做静态作用域;
  3. Python中闭包最常用的场景就是装饰器,关于装饰器在此不展开介绍,将在中高级课程部分再介绍。

老猿Python,跟老猿学Python!
博客地址:https://blog.youkuaiyun.com/LaoYuanPython

请大家多多支持,点赞、评论和加关注!谢谢!

理解Python闭包概念 其实问题的关键就在于在返回闭包列表fs之前for循环的变量的值已经发生改变了,而且这个改变会影响到所有引用它的内部定义的函数。运行的结果也说明了闭包函数中引用的父函数中local variable既不具有C++中的全局变量的性质也没有static变量的行为。函数my_func一旦返回,那么内部定义的函数func便是一个闭包,其中引用的变量j成为一个只和具体闭包相关的自由变量。应该怎么正确的理解呢?C++中有static关键字,函数中的static关键字定义的变量独立于函数之外,而且会保留函数中值的变化。 阅读详情

相关推荐

【闭包】前端的“保护神”——闭包详解+底层原理

它们能够保持对外部数据(如事件触发时的状态、函数参数等)的访问,即使在异步操作完成后,闭包仍然能够访问这些数据。你可以将某些功能封装在闭包内部,外部只能通过公开的方法调用它们,从而达到隐藏细节、减少外部依赖的目的。闭包提供了数据封装的能力,可以将状态和行为封装在一个函数内部,并通过暴露的接口与外部进行交互。闭包可以用于权限管理和角色管理的场景中,通过闭包来封装不同角色的权限信息,从而提供灵活的权限控制。是私有的,外部无法直接访问。,即使这个函数在外部被调用时,依然能访问到其定义时的父函数的局部变量。

代码的魅力,根本走不出来 4585

js闭包的理解

\1. 什么叫闭包? 闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成 " 定义在一个函数内部的函数" 。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。 2.闭包的产生条件? 作用域嵌套 在父级作用域里生成了一个变量 var i=0 在子作用域里使用这个变量,这样声明的那个变量 i 就是自由变量,这种作用域嵌套环境叫做闭包环境。 在内存中存在和回收站相似的机制,叫做垃圾回收机制。...

ysj1218的博客 6916

闭包的定义,闭包是什么?闭包解决了什么问题?闭包有哪些应用场景?使用闭包应该注意什么?

闭包(Closure)是计算机科学中的一个重要概念,特别是在函数式编程中。闭包可以定义为能够读取其他函数内部变量的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。闭包包含自由(未绑定到特定对象)变量,这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义的(局部变量)。

卡拉米 2197

什么是闭包?(详解闭包)

什么是闭包? 闭包的优点。 闭包的缺点。 闭包的作用。 闭包

我只是个很菜的前端 1万+

js的项目13:闭包的案例

闭包的案例 1、点击li输出索引号 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> &

小黄呀呀呀的博客 200

从零做出可发布的2D冒险游戏!Unity全流程实战指南:从资源搭建到打包发布,新手也能跟着做

项目配置→资源导入→核心模块开发→关卡设计→调试→打包发布;玩家控制→敌人AI→道具系统→UI系统→游戏管理器→音效系统;新手开发重点:先实现核心玩法(移动、跳跃、攻击),再补充UI、音效、存档等辅助功能;调试是关键:每实现一个功能就测试,避免最后一堆bug难以定位。从零做一款完整的2D冒险游戏,能快速提升你的Unity综合能力——不仅能掌握C#编程、2D物理、UI系统,还能理解游戏开发的完整流程。先做出基础版,再慢慢迭代优化,你会发现游戏开发并没有想象中那么难。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1176

对闭包的理解

理解闭包

hddlsj的博客 2582

开源TMS系统cortex-tms私有化部署与二次开发实战指南

运输管理系统(TMS)是现代物流数字化的核心组件,它通过将线下零散的物流操作转化为线上标准化、可追溯的数据流,实现订单、调度、跟踪与结算的全流程管理。其技术原理通常基于微服务架构,采用Spring Boot、Vue.js等成熟技术栈构建,确保系统的稳定性和可扩展性。TMS的技术价值在于显著提升物流企业的运营效率、降低成本并增强过程可控性,尤其适用于中小型物流企业实现从手工管理到系统化管理的跨越。在应用场景上,TMS广泛应用于车队管理、订单跟踪和财务结算等环节。本文聚焦于开源TMS项目cortex-tms,深

weixin_42523907的博客 746

【Rust自学】13.1. 闭包 Pt.1:什么是闭包、如何使用闭包

闭包是可以捕获其所在环境的匿名函数。闭包的特点有四:1.闭包是匿名函数 2.这个匿名函数可以保存为变量,或是作为参数传给另一个函数,还可以作为另外一个函数的返回值 3.可以在一个地方创建闭包,然后在另一个上下文中调用闭包来完成运算 4.闭包可以从其定义的作用域内捕获值

A Rookie in San Domenico School 1648

从DIY桌面CNC到工业机器人:手把手教你用LinuxCNC搭建自己的第一台数控系统(基于Xenomai实时补丁)

本文详细介绍了如何使用LinuxCNC和Xenomai实时补丁搭建高性价比的数控系统,从硬件选型到实时系统构建,再到HAL硬件抽象层实战和G代码加工,手把手教你打造从DIY桌面CNC到工业机器人的完整解决方案。

weixin_28727975的博客 288

GEE AI: 利用 Satellite Embedding 语义搜索快速识别研究区目标斑块

摘要 本文介绍了一种基于Google Earth Engine的遥感语义搜索技术,利用Satellite Embedding数据集快速识别目标地物。该方法通过将光谱信息转化为高维向量,在武汉市的案例中展示了如何:1)定义研究区和样本点;2)加载预处理的Embedding数据;3)计算向量相似度;4)结合面积过滤优化结果。相比传统监督分类,该技术具有响应快速(无需模型训练)、抗季节干扰和精准界定等优势,特别适用于森林碳储量监测和土地利用检测等应用场景。文中提供了完整的GEE代码实现流程,包括样本定义、相似度计

此星光明博客 622

【Rust自学】13.2. 闭包 Pt.2:闭包的类型推断和标注

和`fn`定义的函数不同,闭包不强制要求标注参数和返回值的类型。闭包并不会被用于这样的暴露接口,只会被存于变量中,使用时也不需要命名,更不会被暴露给我们代码库的用户。所以,闭包不强制要求标注参数和返回值的类型。

A Rookie in San Domenico School 911

gm/Id 设计方法

本文介绍gm/Id方法的具体实现。

maxwell2ic的博客 4万+

2018/2/13 闭包

闭包在程序语言中,所谓闭包,是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外的执行域上的非持久型变量值能力的段落。这些外部执行域的非持久型变量神奇地保留他们在闭包最初定义(或创建)时的值。白话:  我们可以用一个函数 去访问 另外一个函数的内部变量的方式就是闭包。内部变量是 局部变量      那我们知道,局部变量是不可以为别人随便使用也。 function fun() ...

maggie_xff 171

用户视角下的vfsglobal预约困境:从注册到登录的全流程避坑指南

本文详细解析了vfsglobal签证预约系统从注册到登录的全流程操作,帮助用户避开常见技术陷阱。针对IP限制、DNS解析、浏览器缓存等登录障碍提供实用解决方案,并揭示账号管理的隐藏规则与支付环节的延时处理技巧,助力用户高效完成签证预约。

ol78901234的博客 871

【YOLO目标检测全栈实战】68 模型量化:从FP32到INT8,精度不掉,速度翻倍

摘要: 模型量化能显著提升推理速度(如YOLOv5s帧率从15FPS提升至38FPS),但需避免三大误区:1)校准集需覆盖实际场景,而非随机采样;2)敏感层(如检测头)应保留FP32精度;3)预处理必须与量化前后一致。通过混合精度量化(Backbone用INT8,检测头用FP32)和逐通道量化,可实现<1%的mAP损失。关键步骤包括校准数据准备、量化感知训练及逐层精度评估,最终在Jetson Nano等边缘设备上实现速度与精度的平衡。

企鹅码农的专属播客,分享10多年的实战案例和经验解读,包含YOLO、RT-DETR、AI等各个工作领域。 145

rust笔记13 闭包

闭包是一个可捕获周围环境的可执行代码片段,基本的几个定义方式如下: fn add_one_v1 (x: u32) -> u32 { x + 1 } let add_one_v2 = |x: u32| -> u32 { x + 1 }; let add_one_v3 = |x| { x + 1 }; let add_one_v4 = |x| ...

Erick Lv的笔记 454

Magisk如何针对性隐藏Root避免被检测

Magisk隐藏特征码有两种途径,一种是通过插件,一种是定制源码。插件的方式相对简单,但是使用范围也有限,好处是成本低好上手。定制源码难度大,成本高,好处是稳定,后续也好更新维护。

zhonglunshun的专栏 1万+

13-闭包

闭包是 JavaScript 中最强大也最容易让人困惑的概念之一。理解了闭包,你就理解了函数如何"记住"并访问它的诞生环境。

以梦想为帆,行动作桨,驶向辉煌彼岸。 177

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

day13 闭包

闭包 内部的函数被保存到了外面函数的外面,就会形成闭包。 function a (){ var num = 100; function b (){ num++; console.log(num); } return b; } var demo = a(); demo();//101 deno();//102 a 的执行,导致b 的定义。b.[[scope]]存储着a.AO { num : 100 } 当b 被保存到了外部,b依旧能访问到num 。 demo 第一次执行,num 被修改

weixin_44619186的博客 184

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

什么是闭包,JavaScript闭包详解

JavaScript闭包详解:闭包是函数与可访问的外部变量的组合,具有记忆词法作用域的特性。核心特征在于函数能访问定义时的作用域变量,即使在其他位置执行。常见用途包括封装私有变量、创建函数工厂和处理回调。但需注意内存泄漏风险及循环中的变量共享问题。React Hooks也依赖闭包机制保存状态。理解闭包有助于编写高效灵活的代码,但需正确处理变量引用和生命周期。

qq_44136882的博客 1331

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Python入门13:Python闭包与装饰器

《Python闭包与装饰器:从入门到精通,掌握高级编程技巧》 你是否曾在Python编程中遇到过这样的问题:如何在函数执行后保留局部变量?如何在不修改原函数代码的情况下为其添加新功能?这些问题都可以通过Python中的闭包和装饰器来解决! 本文将带你深入理解Python闭包和装饰器的核心概念,并通过大量代码示例帮助你掌握这些高级编程技巧。无论你是Python初学者,还是有一定经验的开发者,这篇博客都将为你提供宝贵的学习资源。

m0_74488469的博客 1121

Rust(13章闭包)

Rust中的闭包和迭代器的简单概念和例子

weixin_41043435的博客 467

swift学习:13.闭包

本页包含内容: 闭包表达式(Closure Expressions)尾随闭包(Trailing Closures)值捕获(Capturing Values)闭包是引用类型(Closures Are Reference Types) 1.闭包表达式 Swift标准库提供了sorted函数,会根据您提供的基于输出类型排序的闭包函数将已知类型数组中的值进行排序。 一旦排序完成,函数会返

Snow的博客 530

【Rust自学】13.3. 闭包 Pt.3:使用泛型参数和fn trait来存储闭包

闭包在实际使用中经常会被重复调用,造成不必要的耗时。对于这个问题,一个解决方案是把闭包的值赋给某个本地变量,这么写问题的是会造成一些代码的重复。所以这里更适合创建一个结构体,它持有闭包及其调用结果。

A Rookie in San Domenico School 1562

spark系列13:闭包,累加器,广播变量

1. RDD 的分布式共享变量、闭包 目标 理解闭包以及 Spark 分布式运行代码的根本原理 理解累加变量的使用场景 理解广播的使用场景 什么是闭包 闭包是一个必须要理解, 但是又不太好理解的知识点, 先看一个小例子 @Test def test(): Unit = { val areaFunction = closure() val area = areaFunction(2) println(area) } def closure(): Int =&

涤生大数据 1043
上一篇: 第13.1节 关于Python的异常处理
下一篇: 第13.3节 图形界面开发tkinter
LaoYuanPython
LaoYuanPython 2020年博客之星Top3 2020年博客之星Top3 领域专家: Python技术领域 领域专家: Python技术领域
博客等级 码龄8年 15万+粉丝 1324原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LaoYuanPython

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值