Python闭包与闭包陷阱

news2025/1/16 8:02:13

1 什么是闭包

在 Python 中,闭包是一种特殊的函数,它能够记住它所在的环境(也称作上下文)。这意味着闭包能够访问定义它的作用域中的变量。闭包通常用于封装数据和提供对外部访问的接口。

在 Python 中使用闭包有以下几点好处:

  1. 保存状态:闭包可以保存外部函数的状态,以便在内部函数中使用。
  2. 简化代码:闭包可以简化代码结构,使得复杂的逻辑变得简单易懂。
  3. 模块化编程:闭包可以更好地封装代码,提高代码的可重用性。
  4. 保证函数线程安全:闭包可以保证函数的线程安全性,避免全局变量被多线程修改。

2 闭包示例代码

代码示例如下:

def outer_func(x):
    def inner_func(y):
        return x + y
    return inner_func

closure = outer_func(10)
print(closure(5)) # 15

这是一个闭包的示例代码,其中outer_func是外部函数,它返回一个内部函数inner_func。内部函数使用了外部函数的变量x,并且在被调用时使用了参数y。因此,当我们调用outer_func(10)时,它返回了一个闭包(即inner_func),它记录了x=10的值。之后,我们可以调用这个闭包,并传入参数y来计算结果。

3 什么是闭包陷阱

Python中的闭包陷阱指的是在闭包中引用了变量时,如果该变量在闭包外部被修改,则闭包内部的值也会改变。这可能会导致程序的错误或意外行为。

4 闭包陷阱代码实例

请对比以下两组代码

4.1 第一组代码实例

def closure1():
    l = []
    for i in range(3):
        def inner(i_=i):
            return i_**2
        l.append(inner)
    return l


l1 = closure1()
print([i() for i in l1])

在执行代码时,首先i的在range(3)中获取的值为0,接下来执行l.append(inner)。这里inner并没有括号,所以inner本身不会被执行,而是在l中添加了一个inner函数对象。并且inner函数的形参i_默认值为0。
在这里插入图片描述
接下来,在for循环的作用下,l又被重复添加了两次inner对象,其中i_的默认值分别为1和2。
在这里插入图片描述
执行完closure1后,我们使用列表推到式去遍历l1
列表推导式中的i()使得inner对象被执行。因为i()中未传入任何参数,所以其中的i_使用了我们定义的默认参数:0,1,2。在执行完inner函数后,这些数字变成了0,1,4。因此最终的输出即为[0,1,4] 。
以上是一段正常的非闭包代码。

4.2 第二组代码实例

def closure2():
    l = []
    for i in range(3):
        def inner():
            return i**2
        l.append(inner)
    print(inner.__closure__)
    return l


l2 = closure2()
print([i() for i in l2])

这一组代码和上面一组代码没有很大的区别,唯一的差异是,这一组代码的inner并未传入形参i_。inner中的i直接取自外部。
因此,在执行closure2中的for循环时,l中依然会被传入3个inner函数对象,唯一的区别是传入的对象没有指定形参的默认值。
在执行[i() for i in l2]这个列表推到式时,inner函数并未找到对i的赋值,因此回到外部的closure2中去寻找,并找到了i的值为3。
因此,对于这段代码,每一个inner函数对象的输出都是4。
很明显这并不是我们想要的结果,这就是一个典型的闭包陷阱。

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

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

相关文章

数据库和SQL概述

数据库和SQL概述 数据库的好处 实现数据的持久化使用完整的管理系统统一管理,易于查询 常用的一些名称缩写 DB:数据库(Database):存储数据的“仓库”。它保存了一系列有组织的数据DBMS:数据库管理系统(Database Management Sy…

离线用户召回定时更新

3.6 离线用户召回定时更新 学习目标 目标 知道离线内容召回的概念知道如何进行内容召回计算存储规则应用 应用spark完成离线用户基于内容的协同过滤推荐 3.6.1 定时更新代码 完整代码 import os import sys # 如果当前代码文件运行测试需要加入修改路径,否则后面…

游戏启动器:LaunchBox Premium with Big Box v13.1

LaunchBox知道您会喜欢的功能,具有风格的游戏启动器,我们最初将 Launchbox 构建为 DOSBox 的一个有吸引力的前端,但它现在拥有对现代游戏和复古游戏模拟的支持。我们让您的所有游戏看起来都很漂亮。 整理您的游戏收藏 我们不仅漂亮&#xff…

基于微信小程序奶茶店在线点餐下单系统

奶茶在线下单系统用户端是基于微信小程序端,管理员端是基于web端,基于java编程语言,mysql数据库,idea工具开发,用户微信端可以注册登陆小程序,查看奶茶详情,搜索下单奶茶,在线奶茶评…

CSS @property(CSS 自定义属性)

CSS property(CSS 自定义属性)参考描述propertyHoudiniproperty兼容性描述符规则syntax扩展initial-valueinherits示例描述符的注意事项使用 JavaScript 来创建自定义属性CSS 变量与自定义属性重复赋值过渡简单的背景过渡动画更复杂的背景过渡动画错误示…

【ARM体系结构】之数据类型约定与工作模式

1、RISC和CISC的区别 1.1 RISC : 精简指令集 使用精简指令集的架构:ARM架构 RISC-V架构 PowerPC架构 MIPS架构ARM架构 :目前使用最广泛的架构,ARM面向的低端消费类市场RISC-V架构 :第五代,精简指令集的架构&#xff…

这样定义通用人工智能

🍿*★,*:.☆欢迎您/$:*.★* 🍿 正文 人类解决问题的途径,大体可以分为两种。一种是事实推理,另一种是事实验证。 为什么只是两种分类,因为根据和环境的交互与否。 事实推理解释为当遇到事件发生的时候,思考的过程。可以使用概率模型,或者更复杂的模型(目前没…

Out of Vocabulary处理方法

Out of Vocabulary 我们在NLP任务中一般都会有一个词表,这个词表一般可以使用一些大牛论文中的词表或者一些大公司的词表,或者是从自己的数据集中提取的词。但是无论当后续的训练还是预测,总有可能会出现并不包含在词表中的词,这…

(教程)如何在BERT模型中添加自己的词汇(pytorch版)

来源:投稿 作者:皮皮雷 编辑:学姐 参考文章: NLP | How to add a domain-specific vocabulary (new tokens) to a subword tokenizer already trained like BERT WordPiece | by Pierre Guillou | Medium https://medium.com/pi…

ROS2机器人编程简述humble-第三章-BUMP AND GO IN C++ .3

简述本章项目,参考如下:ROS2机器人编程简述humble-第三章-PERCEPTION AND ACTUATION MODELS .1流程图绘制,参考如下:ROS2机器人编程简述humble-第三章-COMPUTATION GRAPH .2然后,在3.3和3.4分别用C和Python编程实现&am…

Bus Hound 工具抓取串口数据(PC端抓取USB转串口数据)

测试环境: PC端 USB转串口 链接终端板卡串口 目标:抓取通信过程中的通信数据 工具介绍:Bus Hound是是由美国perisoft公司研制的一款超级软件总线协议分析器,它是一种专用于PC机各种总线数据包监视和控制的开发工具软件&#xff0c…

通信原理简明教程 | 数字调制传输

文章目录1 二进制数字调制和解调1.1 二进制数字调制的基本原理1.2 二进制数字调制信号的特性1.3 解调方法2 二进制差分相移键控2.1 2PSK的倒π现象2.2 2DPSK调制和解调3 二进制调制系统的抗噪性能3.1 2ASK系统的抗噪声性能3.2 2FSK系统的抗噪声性能4 二进制数字调制系统性能比较…

服务器配置定时脚本 crontab + Python;centos6或centos 7或centos8 实现定时执行 python 脚本

一、crontab的安装 默认情况下,CentOS 7中已经安装有crontab,如果没有安装,可以通过yum进行安装。 yum install crontabs 二、crontab的定时语法说明 corntab中,一行代码就是一个定时任务,其语法结构可以通过这个图来理解。 字符含义如下: * 代表取值范围内的数字 /…

Linux内核驱动初探(三) 以太网卡

目录 0. 前言 1. menuconfig 2. 设备树 0. 前言 这次的网卡驱动就比较顺利,基本就是参考 4.19.x 内核以及 imx6qdl-sabrelite.dtsi、imx6qdl-sabreauto.dtsi 中的设备树,来设置以太网各项参数。 1. menuconfig 其实笔者接手的时候,网口这…

本质安全设备标准(IEC60079-11)的理解(三)

本质安全设备标准(IEC60079-11)的理解(三) 对于标准中“fault”的理解 第一,标准中对fault的定义是这样的: 3.7.2 fault any defect of any component, separation, insulation or connection between c…

C++空间命名

前言 提示:由于C是在C语言基础之上,增加了很多新的东西。 本文讲解命名空间的具体使用方法 文章目录 目录 前言 一、命名空间 二、命名空间定义 1.嵌套性 2.和并性 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一…

【华为上机真题】区间交集

🎈 作者:Linux猿 🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊! &…

CleanMyMac X真的有必要买吗?CleanMyMac2023最新版下载

CleanMyMac X是一款集所有功能于一身的先进程序卸载清理器,只需两个简单步骤就可以把系统里那些乱七八糟的无用文件统统清理掉,节省宝贵的磁盘空间。CleanMyMac为您喜爱的东西腾出空间。它不仅有着赏心悦目的UI交互页面,更有着强大的“超能力…

HTB-BountyHunter

HTB-BountyHunter信息收集开机提权信息收集 80端口的网页如下。 注意有一个db.php,虽然现在打不开,估计后面会用上。 还有resources里面的readme文件。 完成了tracker提交编写和developer组权限。没有完成portal的test用户禁用、选择哈希加密的密码以…

Webshell(网页后门)

数据来源 本文仅用于信息安全的学习,请遵守相关法律法规,严禁用于非法途径。若观众因此作出任何危害网络安全的行为,后果自负,与本人无关。 一、Webshell简介 01 什么是 Webshell webshell是以 asp、php、jsp或者cgi等网页文…