python闭包详解(实例)

发布时间 - 2026-01-10 00:00:00    点击率:
闭包是内部函数引用外部函数局部变量且外部函数返回该内部函数所构成的函数对象。它需满足嵌套函数、使用外部局部变量、返回内部函数三个条件,核心价值在于数据封装与状态保持。

什么是闭包

闭包是指一个函数对象,它不仅包含函数本身,还“记住了”定义时所在作用域中的变量。简单说:**内部函数引用了外部函数的局部变量,并且外部函数返回了这个内部函数**,就构成了闭包。

闭包的三个必要条件

要形成闭包,必须同时满足以下三点:

  • 存在一个嵌套函数(即函数内部定义了另一个函数)
  • 内部函数使用了外部函数的局部变量(非全局变量)
  • 外部函数返回了内部函数(注意:不是调用结果,而是函数名本身)

一个经典例子:计数器

下面是一个生成独立计数器的闭包实例:

def make_counter():
    count = 0  # 外部函数的局部变量
    def counter():
        nonlocal count
        count += 1
        return count
    return counter  # 返回函数对象,不加括号

创建两个独立的计数器

counter_a = make_counter() counter_b = make_counter()

print(counter_a()) # 输出 1 print(counter_a()) # 输出 2 print(counter_b()) # 输出 1(不受 counter_a 影响) print(counter_a()) # 输出 3

这里 count 被两个不同的闭包各自保存,互不干扰——这正是闭包的核心价值:**数据封装与状态保持**。

如何确认一个函数是闭包

Python 中可通过函数对象的 __closure__ 属性判断:

  • 如果 func.__closure__ 不为 None,说明它是闭包
  • func.__closure__ 是一个元组,每个元素是 cell 对象
  • 通过 cell.cell_contents 可读取被捕获的变量值
print(counter_a.__closure__)           # (,)
print(counter_a.__closure__[0].cell_contents)  # 输出 3

闭包常见用途

闭包在实际开发中很实用,典型场景包括:

  • 配置预设:比如固定日志前缀、API 基础 URL
  • 装饰器实现:带参数的装饰器底层依赖闭包
  • 回调函数携带上下文:GUI 或异步编程中避免使用全局变量
  • 延迟求值 / 惰性计算:把参数和逻辑打包,稍后执行

注意:循环中创建闭包的陷阱

下面这段代码常被误解:

funcs = []
for i in range(3):
    funcs.append(lambda: i)
print([f() for f in funcs])  # 输出 [2, 2, 2],不是 [0, 1, 2]

原因:所有 lambda 共享同一个变量 i,循环结束时 i == 2。修复方式是用默认参数捕获当前值:

funcs = []
for i in range(3):
    funcs.append(lambda x=i: x)  # 绑定当前 i 的值到默认参数
print([f() for f in funcs])  # 输出 [0, 1, 2]


# python  # app  # 回调函数  # 作用域 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在阿里云部署织梦网站?  Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  JS经典正则表达式笔试题汇总  Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程  Bootstrap整体框架之CSS12栅格系统  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  如何在腾讯云服务器快速搭建个人网站?  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  如何在万网ECS上快速搭建专属网站?  Swift中switch语句区间和元组模式匹配  BootStrap整体框架之基础布局组件  Laravel如何处理异常和错误?(Handler示例)  高防服务器如何保障网站安全无虞?  Laravel怎么实现验证码(Captcha)功能  Python文本处理实践_日志清洗解析【指导】  Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  制作公司内部网站有哪些,内网如何建网站?  html5audio标签播放结束怎么触发事件_onended回调方法【教程】  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  Laravel如何使用模型观察者?(Observer代码示例)  Laravel Docker环境搭建教程_Laravel Sail使用指南  如何用VPS主机快速搭建个人网站?  Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】  Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】  深圳网站制作的公司有哪些,dido官方网站?  jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】  如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)  活动邀请函制作网站有哪些,活动邀请函文案?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  个人网站制作流程图片大全,个人网站如何注销?  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  php json中文编码为null的解决办法  Android Socket接口实现即时通讯实例代码  如何获取PHP WAP自助建站系统源码?  Laravel如何记录自定义日志?(Log频道配置)  北京企业网站设计制作公司,北京铁路集团官方网站?  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  java获取注册ip实例  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  javascript读取文本节点方法小结  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  做企业网站制作流程,企业网站制作基本流程有哪些?  Laravel如何使用Blade模板引擎?(完整语法和示例)  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  JavaScript中如何操作剪贴板_ClipboardAPI怎么用