Python闭包及装饰器运行原理解析


Posted in Python onJune 17, 2020

一、闭包

闭包从形式上来说是在外部函数中定义内部函数,并且内部函数引用了外部函数的变量,此变量叫做自由变量。

或者说是将组成函数的语句和这些语句的执行环境打包在一起。

闭包满足的条件:

必须有一个内嵌函数

内嵌函数必须使用外部函数的变量

外部函数的返回值必须是内嵌函数

def closure():
 value = []
 def fun(tmp):
  value.append(tmp)
  return value
 return fun

cc = closure() 
cc(0) #[0] 等同于closure(fun(0))
cc(1) #[0,1]
cc(2) #[0,1,2]

外部函数closure中有变量value和内部函数fun,并且内部函数fun引用了自由变量value,当执行cc = closure()时,就产生了一个闭包fun,该闭包持有只有变量value,当函数closure生命周期结束后,value依然存在,因为它被闭包引用了。

二、装饰器

装饰器其实就是闭包的应用,只不过其传递的是函数。

def add_time(fun):
 def wrapper():
  print('time: 12:00')
  return fun()
 return wrapper

def add_format(fun):
 def wrapper():
  print('\n')
  return fun()
 return wrapper

@add_format #等同于demo = add_format(add_time(demo))
@add_time #等同于 demo = add_time(demo)
def demo():
 return 'hello world!'

另外,装饰器会将demo函数的元信息丢失,例如__name__等等。

例如demo函数的__name__会由'demo'变成了'wrapper',这时需要用到functools库,在wrapper函数前加上@functools.wraps(fun):

import functools

def add_time(fun):
 @functools.wraps(fun)
 def wrapper():
  print('time: 12:00')
  return fun()
 return wrapper

def add_format(fun):
 @functools.wraps(fun)
 def wrapper():
  print('\n')
  return fun()
 return wrapper

@add_format #等同于demo = add_format(add_time(demo))
@add_time #等同于 demo = add_time(demo)
def demo():
 return 'hello world!'

例如给任意函数加上打印时间的功能的装饰器:

def metric(fn):
 start=time.time()
 @functools.wraps(fn)
 def wrapper(*args,**kw):
  end=time.time()
  print('%s executed in %s ms' % (fn.__name__,start-end))
  return fn(*args,**kw)
 return wrapper

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
举例讲解Python中的身份运算符的使用方法
Oct 13 Python
举例讲解Python编程中对线程锁的使用
Jul 12 Python
Python安装第三方库及常见问题处理方法汇总
Sep 13 Python
pygame游戏之旅 如何制作游戏障碍
Nov 20 Python
python 实现敏感词过滤的方法
Jan 21 Python
python编写简单端口扫描器
Sep 04 Python
基于Python中isfile函数和isdir函数使用详解
Nov 29 Python
python调用c++返回带成员指针的类指针实例
Dec 12 Python
python列表生成器迭代器实例解析
Dec 19 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
Jun 18 Python
Pytorch上下采样函数--interpolate用法
Jul 07 Python
python获取带有返回值的多线程
May 02 Python
浅谈Python协程
Jun 17 #Python
使用K.function()调试keras操作
Jun 17 #Python
哪些是python中web开发框架
Jun 17 #Python
python如何处理程序无法打开
Jun 16 #Python
python模块如何查看
Jun 16 #Python
python实现PDF中表格转化为Excel的方法
Jun 16 #Python
解决Keras 中加入lambda层无法正常载入模型问题
Jun 16 #Python
You might like
thinkphp自定义权限管理之名称判断方法
2017/04/01 PHP
php 一维数组的循环遍历实现代码
2017/04/10 PHP
Laravel 前端资源配置教程
2019/10/18 PHP
使用Rancher在K8S上部署高性能PHP应用程序的教程
2020/07/10 PHP
jQuery TextBox自动完成条
2009/07/22 Javascript
浅谈tudou土豆网首页图片延迟加载的效果
2010/06/23 Javascript
js实现双向链表互联网机顶盒实战应用实现
2011/10/28 Javascript
JS获取地址栏参数的小例子
2013/08/23 Javascript
javascript dom追加内容实现示例
2013/09/21 Javascript
Javascript连接Access数据库完整实例
2015/08/03 Javascript
JS简单实现String转Date的方法
2016/03/02 Javascript
AngularJS指令中的绑定策略实例分析
2016/12/14 Javascript
input file样式修改以及图片预览删除功能详细概括(推荐)
2017/08/17 Javascript
vue-router重定向不刷新问题的解决
2018/06/25 Javascript
Bootstrap4 gulp 配置详解
2019/01/06 Javascript
JS对象和字符串之间互换操作实例分析
2019/02/02 Javascript
微信小程序背景音乐开发详解
2019/12/12 Javascript
vue实现登录拦截
2020/06/29 Javascript
python简单实现计算过期时间的方法
2015/06/09 Python
python根据日期返回星期几的方法
2015/07/06 Python
详解Python中dict与set的使用
2015/08/10 Python
Bottle框架中的装饰器类和描述符应用详解
2017/10/28 Python
python 求某条线上特定x值或y值的点坐标方法
2019/07/09 Python
tesserocr与pytesseract模块的使用方法解析
2019/08/30 Python
使用virtualenv创建Python环境及PyQT5环境配置的方法
2019/09/10 Python
5行Python代码实现图像分割的步骤详解
2020/05/25 Python
Luxplus瑞典:香水和美容护理折扣
2018/01/28 全球购物
国贸类专业毕业生的求职信分享
2013/12/08 职场文书
岗位廉洁从业承诺书
2014/03/28 职场文书
《画杨桃》教学反思
2014/04/13 职场文书
财务内勤岗位职责
2014/04/17 职场文书
小班上学期评语
2014/05/05 职场文书
小学教师个人先进事迹材料
2014/05/17 职场文书
监守自盗观后感
2015/06/10 职场文书
Python turtle实现贪吃蛇游戏
2021/06/18 Python
解决ubuntu安装软件时,status-code=409报错的问题
2022/12/24 Servers