Python 闭包的使用方法


Posted in Python onSeptember 07, 2017

Python 闭包的使用方法

嵌套函数中的非局部变量

在进入闭包之前,我们必须先了解一个嵌套函数和非局部变量。

在函数中定义另一个函数称为嵌套函数。嵌套函数可以访问包围范围内的变量。

在Python中,这些非局部变量只能在默认情况下读取,我们必须将它们显式地声明为非局部变量(使用nonlocal关键字)才能进行修改。

以下是访问非局部变量的嵌套函数的示例。

def print_msg(msg):
# This is the outer enclosing function

  def printer():
# This is the nested function
    print(msg)

  printer()

# We execute the function
# Output: Hello
print_msg("Hello")

可以看到嵌套函数printer()能够访问封闭函数的非局部变量msg。

定义闭包函数

在上面的例子中,如果函数print_msg()的最后一行返回printer()函数而不是调用它,会发生什么? 如该函数定义如下 -

def print_msg(msg):
# This is the outer enclosing function

  def printer():
# This is the nested function
    print(msg)

  return printer # this got changed

# Now let's try calling this function.
# Output: Hello
another = print_msg("Hello")
another()

这样是不寻常的。

print_msg()函数使用字符串“Hello”进行调用,返回的函数被绑定到另一个名称。 在调用another()时,尽管我们已经完成了print_msg()函数的执行,但仍然记住了这个消息。

一些数据(“Hello”)附加到代码中的这种技术在Python中称为闭包。

即使变量超出范围或函数本身从当前命名空间中删除,也会记住封闭范围内的值。

尝试在Python shell中运行以下内容以查看输出。

>>> del print_msg
>>> another()
Hello
>>> print_msg("Hello")
Traceback (most recent call last):
...
NameError: name 'print_msg' is not defined

什么时候闭包?

从上面的例子可以看出,当嵌套函数引用其封闭范围内的值时,在Python中有使用了一个闭包。

在Python中创建闭包必须满足的标准将在以下几点 -

  • 必须有一个嵌套函数(函数内部的函数)。
  • 嵌套函数必须引用封闭函数中定义的值。
  • 闭包函数必须返回嵌套函数。

何时使用闭包?

那么闭包是什么好的?

闭包可以避免使用全局值并提供某种形式的数据隐藏。它还可以提供面向对象的解决问题的解决方案。

当在类中几乎没有方法(大多数情况下是一种方法)时,闭包可以提供一个替代的和更优雅的解决方案。 但是当属性和方法的数量变大时,更好地实现一个类。

这是一个简单的例子,其中闭包可能比定义类和创建对象更为优先。

def make_multiplier_of(n):
  def multiplier(x):
    return x * n
  return multiplier

# Multiplier of 3
times3 = make_multiplier_of(3)

# Multiplier of 5
times5 = make_multiplier_of(5)

# Output: 27
print(times3(9))

# Output: 15
print(times5(3))

# Output: 30
print(times5(times3(2)))

Python中的装饰器也可以广泛使用闭包。值得注意的是,可以找到封闭函数中包含的值。

所有函数对象都有一个__closure__属性,如果它是一个闭包函数,它返回一个单元格对象的元组。 参考上面的例子,我们知道times3和times5是闭包函数。

>>> make_multiplier_of.__closure__
>>> times3.__closure__
(<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,)

单元格(cell)对象具有存储闭合值的属性:cell_contents。

>>> times3.__closure__[0].cell_contents
3
>>> times5.__closure__[0].cell_contents
5

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Python 相关文章推荐
Django中实现一个高性能计数器(Counter)实例
Jul 09 Python
pymssql数据库操作MSSQL2005实例分析
May 25 Python
Python实现模拟浏览器请求及会话保持操作示例
Jul 30 Python
Django 导出项目依赖库到 requirements.txt过程解析
Aug 23 Python
解决python 读取 log日志的编码问题
Dec 24 Python
pytorch 图像中的数据预处理和批标准化实例
Jan 15 Python
postman和python mock测试过程图解
Feb 22 Python
django 多数据库及分库实现方式
Apr 01 Python
django Layui界面点击弹出对话框并请求逻辑生成分页的动态表格实例
May 12 Python
python logging模块的使用详解
Oct 23 Python
手残删除python之后的补救方法
Jun 26 Python
Python 阶乘详解
Oct 05 Python
Python基于回溯法子集树模板解决选排问题示例
Sep 07 #Python
Python基于回溯法子集树模板解决全排列问题示例
Sep 07 #Python
python中利用await关键字如何等待Future对象完成详解
Sep 07 #Python
Python基于回溯法子集树模板解决m着色问题示例
Sep 07 #Python
python中利用Future对象异步返回结果示例代码
Sep 07 #Python
python中利用Future对象回调别的函数示例代码
Sep 07 #Python
Python标准库之itertools库的使用方法
Sep 07 #Python
You might like
模拟xcopy的函数
2006/10/09 PHP
AMFPHP php远程调用(RPC, Remote Procedure Call)工具 快速入门教程
2010/05/10 PHP
php中实现简单的ACL 完结篇
2011/09/07 PHP
php中switch语句用法详解
2015/08/17 PHP
替代window.event.srcElement效果的可兼容性的函数
2009/12/18 Javascript
JQuery+Ajax实现数据查询、排序和分页功能
2015/09/27 Javascript
超实用的JavaScript表单代码段
2016/02/26 Javascript
jQuery+CSS3+Html5实现弹出层效果实例代码(附源码下载)
2016/05/16 Javascript
JS获取复选框的值,并传递到后台的实现方法
2016/05/30 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
2016/07/22 Javascript
JQuery遍历元素的父辈和祖先的方法
2016/09/18 Javascript
js改变html的原有内容实现方法
2016/10/05 Javascript
javaScript生成支持中文带logo的二维码(jquery.qrcode.js)
2017/01/03 Javascript
巧用canvas
2017/01/21 Javascript
node vue项目开发之前后端分离实战记录
2017/12/13 Javascript
使用layui前端框架弹出form表单以及提交的示例
2019/10/25 Javascript
JS实现吸顶特效
2020/01/08 Javascript
JavaScript实现滑动门效果
2020/01/18 Javascript
使用原生JS实现滚轮翻页效果的示例代码
2020/05/31 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
2020/07/22 Javascript
javascript实现扫雷简易版
2020/08/18 Javascript
python实现随机密码字典生成器示例
2014/04/09 Python
Python中的MongoDB基本操作:连接、查询实例
2015/02/13 Python
Python函数式编程指南(三):迭代器详解
2015/06/24 Python
Python利用正则表达式匹配并截取指定子串及去重的方法
2015/07/30 Python
Python实现字典的key和values的交换
2015/08/04 Python
python实现DEM数据的阴影生成的方法
2019/07/23 Python
Lacoste澳大利亚官网:服装、鞋类及配饰
2018/11/14 全球购物
美国现代家具购物网站:LexMod
2019/01/09 全球购物
Emma Bridgewater官网:英国餐具制造商
2019/11/24 全球购物
县人大领导班子四风对照检查材料思想汇报
2014/10/09 职场文书
先进党支部申报材料
2014/12/24 职场文书
装饰技术负责人岗位职责
2015/04/13 职场文书
高中开学感言
2015/08/01 职场文书
如何使用Python提取Chrome浏览器保存的密码
2021/06/09 Python
python游戏开发Pygame框架
2022/04/22 Python