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 相关文章推荐
python获取指定网页上所有超链接的方法
Apr 04 Python
用Python编写生成树状结构的文件目录的脚本的教程
May 04 Python
Python基于正则表达式实现检查文件内容的方法【文件检索】
Aug 30 Python
python实现识别手写数字 python图像识别算法
Mar 23 Python
python正则表达式匹配[]中间为任意字符的实例
Dec 25 Python
Python multiprocess pool模块报错pickling error问题解决方法分析
Mar 20 Python
TensorFlow车牌识别完整版代码(含车牌数据集)
Aug 05 Python
Python面向对象原理与基础语法详解
Jan 02 Python
Django单元测试中Fixtures用法详解
Feb 25 Python
Window系统下Python如何安装OpenCV库
Mar 05 Python
基于Python实现粒子滤波效果
Dec 01 Python
python字符串拼接+和join的区别详解
Dec 03 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
php Smarty模板生成html文档的方法
2010/04/12 PHP
隐藏Nginx或Apache以及PHP的版本号的方法
2016/01/03 PHP
PHP页面输出时js设置input框的选中值
2016/09/30 PHP
PHP读取文件,解决中文乱码UTF-8的方法分析
2020/01/22 PHP
Prototype PeriodicalExecuter对象 学习
2009/07/19 Javascript
jQuery EasyUI API 中文文档 - Draggable 可拖拽
2011/09/29 Javascript
jquery 实现密码框的显示与隐藏示例代码
2013/09/18 Javascript
jquery单行文字向上滚动效果的实现代码
2014/09/05 Javascript
javascript手风琴下拉菜单实现代码
2015/11/12 Javascript
Vuejs第十一篇组件之slot内容分发实例详解
2016/09/09 Javascript
Vuex之理解Mutations的用法实例
2017/04/19 Javascript
利用angular、react和vue实现相同的面试题组件
2018/02/19 Javascript
详解NodeJS Https HSM双向认证实现
2019/03/12 NodeJs
Python多线程结合队列下载百度音乐的方法
2015/07/27 Python
Python三级目录展示的实现方法
2016/09/28 Python
pandas中Timestamp类用法详解
2017/12/11 Python
python导出chrome书签到markdown文件的实例代码
2017/12/27 Python
Python实现动态添加属性和方法操作示例
2018/07/25 Python
Python 写入训练日志文件并控制台输出解析
2019/08/13 Python
深入浅析Python科学计算库Scipy及安装步骤
2019/10/12 Python
浅谈python输出列表元素的所有排列形式
2020/02/26 Python
Python对象的属性访问过程详解
2020/03/05 Python
Python+OpenCV图像处理—— 色彩空间转换
2020/10/22 Python
python中re模块知识点总结
2021/01/17 Python
分享全球十款超强HTML5开发工具
2014/05/14 HTML / CSS
h5封装下拉刷新
2020/08/25 HTML / CSS
Blue Nile中国官网:全球知名的钻石和珠宝网络零售商
2020/03/22 全球购物
经典c++面试题六
2012/01/18 面试题
制作部班长职位说明书
2014/02/26 职场文书
车辆转让协议书
2014/04/15 职场文书
2014年六一儿童节演讲稿
2014/05/23 职场文书
机电系毕业生求职信
2014/07/11 职场文书
四风查摆剖析材料
2014/10/10 职场文书
详解Python内置模块Collections
2022/03/22 Python
关于的python五子棋的算法
2022/05/02 Python
Python通用验证码识别OCR库ddddocr的安装使用教程
2022/07/07 Python