Python闭包思想与用法浅析


Posted in Python onDecember 27, 2018

本文实例讲述了Python闭包思想与用法。分享给大家供大家参考,具体如下:

浅谈 python 的闭包思想

首先 python的闭包使用方法是:在方法A内添加方法B,然后return 方法B 注意,return的时候不要添加任何参数,包括()

这样,通过调用方法A 返回的是一个function 对象,如 demo=方法A 可以直接使用 demo(参数) 将调用方法B 这里不用关注方法B的方法名,

只需要关注参数就可以了,demo(参数) 这里的参数其实就是闭包的方法B的参数,可以多个参数或者元祖一起使用。

其次 在Python中创建一个闭包可以归结为以下三点:

  • 闭包函数必须有内嵌函数
  • 内嵌函数需要引用该嵌套函数上一级namespace中的变量
  • 闭包函数必须返回内嵌函数

对,没错,python的装饰器就是使用了闭包。

好吧,最后再举个栗子:

def test1(prefix):
  def test2(name):
    print('test2闭包内:',name)
  def test3(*name1):
    print('test3 闭包内:',name1)
  return test3
m = test1('prefix')
m("haha",'heihei')

打印结果:

D:\python\python.exe D:/Python_day/day1.py
test3 闭包内: ('haha', 'heihei')

这个例子说明,当函数 test1 的生命周期结束之后,test1('prefix') 中的参数 prefix 这个变量依然存在,生命周期不会随着函数调用结束而消失。

为啥要用闭包呢? 感觉这个功能一般啊,毕竟回调函数是死的,只能回调一个,但是有个函数就是能生成无数个对象,嗯,是的,这玩意和类的功能有点相似。闭包可以被理解为一个只读的对象,你可以给他传递一个属性,但它只能提供给你一个执行的接口,这就牵扯到的另一个特性:惰性求值

如:

# 伪代码示意
class QuerySet(object):
  def __init__(self, sql):
    self.sql = sql
    self.db = Mysql.connect().corsor() # 伪代码
  def __call__(self):
    return db.execute(self.sql)
  def query(sql):
    return QuerySet(sql)
result = query("select name from user_app")
if time > now:
  print result # 这时才执行数据库访问

上面这个不太恰当的例子展示了通过闭包完成惰性求值的功能,但是上面query返回的结果并不是函数,而是具有函数功能的类。有兴趣的可以去看看Django的queryset的实现,原理类似。

还有另一种用处:需要对某个函数的参数提前赋值的情况,当然在Python中已经有了很好的解决访问 functools.parial,但是用闭包也能实现。

如:

def partial(**outer_kwargs):
  def wrapper(func):
    def inner(*args, **kwargs):
      for k, v in outer_kwargs.items():
        kwargs[k] = v
      return func(*args, **kwargs)
    return inner
  return wrapper
@partial(age=15)
def say(name=None, age=None):
  print name, age
say(name="the5fire")
# 当然用functools比这个简单多了
# 只需要: functools.partial(say, age=15)(name='the5fire')

对于工厂函数的理解,感觉和闭包类似,在创建主函数后返回的对象,可以直接传参使用,其实这里返回的对象,就是一个类。

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python中dict字典的查询键值对 遍历 排序 创建 访问 更新 删除基础操作方法
Sep 13 Python
Python多线程处理实例详解【单进程/多进程】
Jan 30 Python
Python参数类型以及常见的坑详解
Jul 08 Python
python中append实例用法总结
Jul 30 Python
利用Python校准本地时间的方法教程
Oct 31 Python
python中dict()的高级用法实现
Nov 13 Python
Python Tornado批量上传图片并显示功能
Mar 26 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
Apr 08 Python
Pyinstaller加密打包应用的示例代码
Jun 11 Python
如何使用python记录室友的抖音在线时间
Jun 29 Python
Python3安装模块报错Microsoft Visual C++ 14.0 is required的解决方法
Jul 28 Python
pycharm如何使用anaconda中的各种包(操作步骤)
Jul 31 Python
对python操作kafka写入json数据的简单demo分享
Dec 27 #Python
python消费kafka数据批量插入到es的方法
Dec 27 #Python
Python通过paramiko远程下载Linux服务器上的文件实例
Dec 27 #Python
Python基于Tkinter模块实现的弹球小游戏
Dec 27 #Python
python 读取Linux服务器上的文件方法
Dec 27 #Python
Python 脚本获取ES 存储容量的实例
Dec 27 #Python
Python数据结构之栈、队列及二叉树定义与用法浅析
Dec 27 #Python
You might like
功能齐全的PHP发送邮件类代码附详细说明
2008/07/10 PHP
php 随机记录mysql rand()造成CPU 100%的解决办法
2010/05/18 PHP
PHP和Mysqlweb应用开发核心技术 第1部分 Php基础-1 开始了解php
2011/07/03 PHP
Yii2.0多文件上传实例说明
2017/07/24 PHP
PHP设计模式之原型模式定义与用法详解
2018/04/03 PHP
针对PHP开发安全问题的相关总结
2019/03/22 PHP
Laravel等框架模型关联的可用性浅析
2019/12/15 PHP
PHP实现倒计时功能
2020/11/16 PHP
子窗口、父窗口和Silverlight之间的相互调用
2010/08/16 Javascript
nodejs win7下安装方法
2012/05/24 NodeJs
ie支持function.bind()方法实现代码
2012/12/27 Javascript
js实现div的切换特效上一个下一个
2014/02/11 Javascript
javascript实现字符串反转的方法
2015/02/05 Javascript
浅析Node.js中使用依赖注入的相关问题及解决方法
2015/06/24 Javascript
详解JavaScript的变量和数据类型
2015/11/27 Javascript
JS简单实现浮动窗口效果示例
2016/09/07 Javascript
JavaScript ES6中CLASS的使用详解
2016/11/22 Javascript
JS设计模式之观察者模式实现实时改变页面中金额数的方法
2018/02/05 Javascript
vue移动端路由切换实例分析
2018/05/14 Javascript
Js生成随机数/随机字符串的方法小结【5种方法】
2020/05/27 Javascript
Python中标准模块importlib详解
2017/04/16 Python
python使用tkinter实现简单计算器
2018/01/30 Python
django 数据库连接模块解析及简单长连接改造方法
2019/08/29 Python
Python爬虫实现的根据分类爬取豆瓣电影信息功能示例
2019/09/15 Python
Python装饰器使用你可能不知道的几种姿势
2019/10/25 Python
python:动态路由的Flask程序代码
2019/11/22 Python
HTML5公共页面提取作为公用代码的方法
2020/06/30 HTML / CSS
网站域名和主机:Domain.com
2019/04/01 全球购物
如何利用cmp命令比较文件
2016/04/11 面试题
经理秘书岗位职责
2013/11/14 职场文书
《望洞庭》教学反思
2014/02/16 职场文书
开学季活动策划方案
2014/02/28 职场文书
学校师德承诺书
2014/05/23 职场文书
学校教师读书活动总结
2014/07/08 职场文书
2014年变电站工作总结
2014/12/19 职场文书
酒店销售经理岗位职责
2015/04/02 职场文书