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 socket.error: [Errno 98] Address already in use的原因和解决方法
Aug 25 Python
在Mac OS系统上安装Python的Pillow库的教程
Nov 20 Python
python面向对象_详谈类的继承与方法的重载
Jun 07 Python
PyChar学习教程之自定义文件与代码模板详解
Jul 17 Python
Python编程之微信推送模板消息功能示例
Aug 21 Python
基于Python函数的作用域规则和闭包(详解)
Nov 29 Python
python使用matplotlib画柱状图、散点图
Mar 18 Python
Python自动化运维之Ansible定义主机与组规则操作详解
Jun 13 Python
python保留小数位的三种实现方法
Jan 07 Python
TensorFlow2.1.0安装过程中setuptools、wrapt等相关错误指南
Apr 08 Python
pandas.DataFrame.drop_duplicates 用法介绍
Jul 06 Python
用于ETL的Python数据转换工具详解
Jul 21 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设计模式 php实现装饰器模式(decorator)
2015/12/07 PHP
PHP序列化的四种实现方法与横向对比
2018/11/29 PHP
ThinkPHP5&amp;5.1实现验证码的生成、使用及点击刷新功能示例
2020/02/07 PHP
php中yar框架实例用法讲解
2020/12/27 PHP
告诉大家什么是JSON
2008/06/10 Javascript
jQuery DIV弹出效果实现代码
2009/07/03 Javascript
js 字符串操作函数
2009/07/25 Javascript
jQuery表格插件datatables用法总结
2014/09/05 Javascript
Node.js中安全调用系统命令的方法(避免注入安全漏洞)
2014/12/05 Javascript
jQuery点缩略图弹出层显示大图片
2015/02/13 Javascript
js禁止页面刷新与后退的方法
2015/06/08 Javascript
简述JavaScript对传统文档对象模型的支持
2015/06/16 Javascript
详解Vue+axios+Node+express实现文件上传(用户头像上传)
2018/08/10 Javascript
深入理解vue中的slot与slot-scope
2019/04/22 Javascript
浅析vue-router实现原理及两种模式
2020/02/11 Javascript
Vue(定时器)解决mounted不能获取到data中的数据问题
2020/07/30 Javascript
[02:32]DOTA2英雄基础教程 美杜莎
2014/01/07 DOTA
[48:32]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 LGD vs VG
2018/04/01 DOTA
跟老齐学Python之??碌某?? target=
2014/09/12 Python
使用Python程序抓取新浪在国内的所有IP的教程
2015/05/04 Python
用python处理图片实现图像中的像素访问
2018/05/04 Python
python线程池如何使用
2020/05/28 Python
python爬虫请求头设置代码
2020/07/28 Python
Django执行源生mysql语句实现过程解析
2020/11/12 Python
python通用数据库操作工具 pydbclib的使用简介
2020/12/21 Python
css3实现3D文本悬停改变效果的示例代码
2019/01/16 HTML / CSS
Ann Taylor官方网站:美国最大的女性产品制造商之一
2016/09/14 全球购物
Farfetch美国:奢侈品牌时尚购物平台
2019/05/02 全球购物
Michael Kors香港官网:美国奢侈品品牌
2019/12/26 全球购物
sort命令的作用和用法
2013/08/25 面试题
爱护花草树木的标语
2014/06/11 职场文书
我们的节日国庆活动方案
2014/08/19 职场文书
民主评议党员个人总结
2015/02/13 职场文书
雷锋观后感
2015/06/10 职场文书
单身狗福利?Python爬取某婚恋网征婚数据
2021/06/03 Python
HashMap实现保存两个key相同的数据
2021/06/30 Java/Android