热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python闭包的详细介绍

在计算机科学中,闭包(Closure)是词法闭包(LexicalClosure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

我更倾向于后一种,把闭包看做一种组织代码的结构,原因我后面解释。

那闭包代码结构是怎样的呢?

Python中,一切皆对象,这当然包括函数了。函数对象可以赋值给一个变量,而且通过这个变量可以调用该函数;函数对象也作为参数进行传递,也可以作为某个函数的返回结果。而且,Python中,函数可以嵌套定义。

Python以函数对象为基础,为闭包这一语法结构提供支持

先看一个例子

def f1():
    name1 = 'Alice'
    name2 = 'Bob'
    def f2():
        print('hello,%s,%s' %(name1,name2))    return f2 


if __name__ == '__main__':
    name1 = 'David'
    name2 = 'Frank'
    func = f1()
    func()
    print(func.__closure__)
    print(func.__closure__[0].cell_contents)
    print(func.__closure__[1].cell_contents)# 输出hello,Alice,Bob
(, )
Alice
Bob

函数 f2 定义在函数 f1 的内部,并且调用了 f1 内定义的变量name1 和 name2 。

f1 返回了 f2 这个函数对象,而实际上返回的 f2 中已经包括了 f1 中的变量name1 和name2,这一点从代码的运行结果中就可以看出来。

在主程序中,虽然重新定义了name1 和name2,但函数 func 执行时调用的仍然是定义时的变量值,即它的引用环境变量,而不是使用时的变量值。

总结一下,Python中,闭包就是一个包含了函数和引用环境变量的代码块,我倾向于把闭包看做一种代码结构,而不是函数,是因为第一次调用它的时候,只是把闭包的引用环境和内部的函数包装在一起,以一个函数对象来返回,而没有执行内部的函数,当调用这个函数对象时,才会执行内部的函数功能。

引用环境变量的值被保存在函数对象的closure属性中。closure里包含了一个元组(tuple)。这个元组中的每个元素是cell类型的对象。我们看到第一个cell包含的就是Alice,也就是我们创建闭包时的环境变量name1的取值。这一点从上面代码的运行结果中可以看出来。

现在回头看一看,百科对闭包的解释。

现在,再举一个例子:

# 此例子转自伯乐在线def line_def(a, b):
    def line(x):
        return a * x + b    return lineif __name__ == '__main__':
    func = line_def(2, 3)
    print(func(5))# 输出13

在这个例子中,函数line和环境变量 a, b 构成了闭包,我们只需改变a, b 的值就能获得不同的直线函数 line,提高了封装性,使得我们只需关注参数a, b就可以了,不要关心内部直线的实现。

闭包的最大特点是可以将外部函数的变量与内部函数绑定,并返回绑定变量后的函数(也即闭包),此时即便生成闭包的环境(外部函数)已经释放,闭包仍然存在。

闭包的一大应用就是装饰器,只不过其传递的是函数。这个下次再写。

以上就是Python闭包的详细介绍的详细内容,更多请关注 第一PHP社区 其它相关文章!


推荐阅读
  • Awk是一款功能强大的文本分析与处理工具,尤其在数据解析和报告生成方面表现突出。它通过读取由换行符分隔的记录,并按照指定的字段分隔符来划分和处理这些记录,从而实现复杂的数据操作。 ... [详细]
  • 本文将指导您如何在Windows 7操作系统中轻松调整屏幕亮度,以达到节能和护眼的效果。 ... [详细]
  • 本文介绍了如何在 Oracle 数据库中查询重复数据,并提供了多种方法来筛选和删除重复记录,包括基于单个字段和多个字段的重复数据处理。 ... [详细]
  • 本文综述了沙尘天气的气象条件,特别关注北京地区的沙尘污染特征,探讨了沙尘期间的气溶胶光学厚度变化、大颗粒物浓度上升以及冷锋作为重要起沙条件的作用。 ... [详细]
  • 深入解析Unity3D游戏开发中的音频播放技术
    在游戏开发中,音频播放是提升玩家沉浸感的关键因素之一。本文将探讨如何在Unity3D中高效地管理和播放不同类型的游戏音频,包括背景音乐和效果音效,并介绍实现这些功能的具体步骤。 ... [详细]
  • 本文详细探讨了能力模型(Competency Model)的概念及其在人力资源管理中的应用,涵盖职位体系设计、薪酬激励策略及绩效管理等方面。通过深入分析冰山模型的核心构成,以及不同类型人才的关键素质,旨在为企业提供科学的人才管理和发展的指导。 ... [详细]
  • 本文提供了处理WordPress网站中出现过多重定向问题的方法,包括检查DNS配置、安装SSL证书以及解决数据库连接错误等步骤。 ... [详细]
  • 解决ADODB连接Access时出现80004005错误的方法
    本文详细介绍了如何解决在使用ADODB连接Access数据库时遇到的80004005错误,包括错误原因分析和具体的解决步骤。 ... [详细]
  • 本文探讨了一种常见的C++面试题目——实现自己的String类。通过此过程,不仅能够检验开发者对C++基础知识的掌握程度,还能加深对其高级特性的理解。文章详细介绍了如何实现基本的功能,如构造函数、析构函数、拷贝构造函数及赋值运算符重载等。 ... [详细]
  • 随着Linux操作系统的广泛使用,确保用户账户及系统安全变得尤为重要。用户密码的复杂性直接关系到系统的整体安全性。本文将详细介绍如何在CentOS服务器上自定义密码规则,以增强系统的安全性。 ... [详细]
  • 本文对宋代著名诗人吕渭老的作品《情久长》进行了细致的翻译和赏析,深入探讨了诗中蕴含的情感与艺术特色。 ... [详细]
  • 本文详细介绍如何安装和配置DedeCMS的移动端站点,包括新版本安装、老版本升级、模板适配以及必要的代码修改,以确保移动站点的正常运行。 ... [详细]
  • 本文提供了一种通过调整内核电压来增强设备抗干扰能力的方法,以解决部分杰里AC696X设备在LDO15模式下通话时出现的重启问题。 ... [详细]
  • 探讨了在HTML表单中使用元素代替进行表单提交的方法。 ... [详细]
  • 如何在PPT中创建交互式跳转按钮
    许多企业在日常工作中都会用到PPT,但你知道如何在PPT中制作一个可以实现页面跳转的按钮吗?本文将详细介绍在PPT中创建跳转按钮的方法和步骤。 ... [详细]
author-avatar
G2602914553
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有