当前位置: 首页 > news >正文

Python闭包:函数嵌套的魔力

概念

官方定义:闭包(Closure)是 Python 中一种特殊的函数嵌套现象:内层函数引用了外层函数的变量(非全局变量),且外层函数返回了这个内层函数。简单来说,闭包让内层函数 “记住” 了外层函数的变量环境,即使外层函数已经执行完毕,内层函数依然能访问和使用这些变量。

狭隘的理解,闭包就是函数嵌套函数。

但是满足闭包,需满足3个条件(如下图代码)

1.存在函数嵌套

2.内层函数引用外层函数变量(非全局变量)

3.外层函数返回内层函数

def outer(): print('outer...') x = 10 def inner(): # 1.函数嵌套 print('inner') return x + 1 # 2.引用外层函数变量 return inner # 3.返回内层函数 a = outer() print(a())

如上代码,a = outer()执行完返回inner,这里a引用的就是inner,此时打印a,打印的是a的内存地址。

<function outer.<locals>.inner at 0x0000020552E7A290>

a()执行,相当于调用内层函数。

图解

当外层函数执行以后,此时有了内层函数的定义和外层函数的变量a和变量b,这个时候再把内层函数吐出来,注意,吐出来的环境包括内层函数和变量a,并不包含变量b,因为内层函数并没有引用变量b。

可能你想,这么做有什么意义?比如,变量记忆、定制函数。

案例

现有这样的需求,普通用户折扣95折,vip用户折扣8折,买100元商品后,普通用户和vip用户折扣后的金额是多少?

常用的思路:

def funcA(discount, price): return discount * price res1 = funcA(0.95, 100) print(f"普通用户,100元优惠价格是,{res1}") res2 = funcA(0.8, 100) print(f"vip用户,100元优惠价格是,{res2}")

调用的时候传discount,本身这样设计没有问题,除了繁琐没毛病(重复传折扣)。那有没有办法,不管是普通用户还是vip用户,调用的时候只要传price就行?

def outer(discount): def inner(price): return discount * price return inner normal = outer(0.95) vip = outer(0.8) print(f"普通用户,100元优惠价格是,{normal(100)}") print(f"普通用户,100元优惠价格是,{vip(100)}")

很明显,同样的一个规则,衍生出来两个函数。函数normal用于普通用户折扣计算,函数vip用于vip用户折扣计算(定制函数),首次调用后,折扣值(discount)被保存下来(变量记忆)。后续计算只需要传价格即可,代码复用性强。如果折扣变化,修改一处即可,如果是之前的方式,则牵一发而动全身。

PS:如果需要修改外层函数的变量值,需要使用nonlocal,如下图

def outer(): print('outer...') x = 10 def inner(): print('inner') nonlocal x x = x + 1 return x return inner
http://www.jsqmd.com/news/528707/

相关文章:

  • 2026年聊聊大阪新房选购要点,这些品牌值得关注 - 工业设备
  • PeanutKing Soccer机器人控制库:分层架构与P5轻量协议解析
  • SpringBoot服务管理避坑指南:BAT脚本中那些你可能忽略的细节(含内存配置优化)
  • OpenRGB:解放你的RGB设备,突破品牌壁垒的一站式控制中心
  • BetterNCM-Installer:网易云音乐插件自动化部署的一站式解决方案——提升安装效率与兼容性的技术实践
  • npm install 会更新package-lock吗
  • 2026年焊接辅助设备厂家推荐:深圳凯德盛机械设备有限公司,全系坡口机解决方案 - 品牌推荐官
  • 设计稿智能转换的颠覆性突破:从像素还原到跨平台代码生成的效能革命
  • 智能家居集成新标杆:HomeAssistant与小米设备的颠覆式体验
  • GME多模态向量模型效果实测:动态分辨率图片搜索展示
  • 日本高度人才签证代理怎么选,侨领靠谱不 - 工业品网
  • EmuDeck:Linux掌机模拟器的自动化配置解决方案
  • 2026年抽沙船厂家推荐:青州科大环保机械,绞吸/射吸/大型/小型抽沙船全系供应 - 品牌推荐官
  • Pixel Mind Decoder 开源生态集成:在LangChain中构建情绪分析链
  • servlet基础
  • Elden Ring FPS Unlock And More:内存补丁技术深度解析与实战指南
  • Windows版Redis本地后台启动
  • 深夜学习助手:OpenClaw+nanobot定时收集技术文章并摘要
  • 零基础玩转掌机模拟器:开源工具的一站式配置攻略
  • Notepad Next:跨平台文本编辑的5个隐藏技巧与终极指南
  • 双三相永磁同步电机模型预测转矩控制
  • 智能体来袭:利用LangChain构建自动化的“日志分析与告警降噪”Agent
  • 作业中的AI成分越来越多怎么办?
  • Windows系统下Python 3.11环境搭建与实战入门
  • ControlNet-v1-1_fp16_safetensors:3大核心机制深度剖析与实战应用
  • 手把手教你用银尔达YED-M100PG-C1模块,5分钟搞定GPS+4G数据透传
  • MyMacros:嵌入式Arduino板卡元数据管理库
  • 告别英文困扰:3分钟解锁Axure中文界面,设计效率翻倍
  • 颠覆性全链路重构:FigmaToCode如何重塑设计开发范式
  • Zotero SciPDF插件:5步实现学术文献PDF自动下载的完整指南