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解析xml文件操作实例
Oct 05 Python
Python写入CSV文件的方法
Jul 08 Python
python 通过xml获取测试节点和属性的实例
Mar 31 Python
python实现将一个数组逆序输出的方法
Jun 25 Python
Python Django给admin添加Action的方法实例详解
Apr 29 Python
一行python实现树形结构的方法
Aug 09 Python
Python绘制热力图示例
Sep 27 Python
Pytorch 搭建分类回归神经网络并用GPU进行加速的例子
Jan 09 Python
Python while循环使用else语句代码实例
Feb 07 Python
python操作yaml说明
Apr 08 Python
Python3安装模块报错Microsoft Visual C++ 14.0 is required的解决方法
Jul 28 Python
Python 虚拟环境工作原理解析
Dec 24 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截取中文字符串不乱码的方法
2013/12/25 PHP
php调用C代码的实现方法
2014/03/11 PHP
PHP判断指定时间段的2个方法
2014/03/14 PHP
php实现随机显示图片方法汇总
2015/05/21 PHP
解决php-fpm.service not found问题的办法
2017/06/06 PHP
Laravel-admin之修改操作日志的方法
2019/09/30 PHP
使用Modello编写JavaScript类
2006/12/22 Javascript
快速查找数组中的某个元素并返回下标示例
2013/09/03 Javascript
js图片预加载示例
2014/04/30 Javascript
深入理解JavaScript系列(39):设计模式之适配器模式详解
2015/03/04 Javascript
jQuery的position()方法详解
2015/07/19 Javascript
javascript设计简单的秒表计时器
2020/09/05 Javascript
利用JS轻松实现获取表单数据
2016/12/06 Javascript
js图片轮播手动切换特效
2017/01/12 Javascript
jQuery代码实现实时获取时间
2017/01/29 Javascript
jQuery 添加样式属性的优先级别方法(推荐)
2017/06/08 jQuery
vue的无缝滚动组件vue-seamless-scroll实例
2017/12/18 Javascript
如何让node运行es6模块文件及其原理详解
2018/12/11 Javascript
webpack3里使用uglifyjs压缩js时打包报错的解决
2018/12/13 Javascript
vscode中Vue别名路径提示的实现
2020/07/31 Javascript
Vue实现开关按钮拖拽效果
2020/09/22 Javascript
[06:14]《辉夜杯》外卡赛附加赛 4支战队巡礼
2015/10/23 DOTA
跟老齐学Python之私有函数和专有方法
2014/10/24 Python
在Python中操作列表之List.append()方法的使用
2015/05/20 Python
python使用MySQLdb访问mysql数据库的方法
2015/08/03 Python
Python3.5内置模块之random模块用法实例分析
2019/04/26 Python
详解Selenium+PhantomJS+python简单实现爬虫的功能
2019/07/14 Python
Linux下升级安装python3.8并配置pip及yum的教程
2020/01/02 Python
史泰博(Staples)中国官方网站:办公用品一站式采购
2016/09/05 全球购物
美国环保婴儿用品公司:The Honest Company
2017/11/23 全球购物
教育专业自荐书范文
2013/12/17 职场文书
文秘班元旦晚会活动策划方案
2014/08/28 职场文书
2014年卫生保健工作总结
2014/12/08 职场文书
个人总结与自我评价
2015/02/14 职场文书
公司考勤管理制度
2015/08/04 职场文书
2019年工作总结范文
2019/05/21 职场文书