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 相关文章推荐
浅谈MySQL中的触发器
May 05 Python
Python简单获取自身外网IP的方法
Sep 18 Python
Python字典操作详细介绍及字典内建方法分享
Jan 04 Python
Python获取指定字符前面的所有字符方法
May 02 Python
Python实现的字典排序操作示例【按键名key与键值value排序】
Dec 21 Python
Python3的高阶函数map,reduce,filter的示例详解
Jul 23 Python
python 进程间数据共享multiProcess.Manger实现解析
Sep 23 Python
flask框架json数据的拿取和返回操作示例
Nov 28 Python
Tkinter中复选菜单是否被选中的判断与设置方式
Mar 04 Python
基于python图像处理API的使用示例
Apr 03 Python
Tensorflow tf.nn.atrous_conv2d如何实现空洞卷积的
Apr 20 Python
Python之qq自动发消息的示例代码
Feb 18 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
PHP开发过程中常用函数收藏
2009/12/14 PHP
求PHP数组最大值,最小值的代码
2011/10/31 PHP
php生成RSS订阅的方法
2015/02/13 PHP
php获取、检查类名、函数名、方法名的函数方法
2015/06/25 PHP
深入探究PHP的多进程编程方法
2015/08/18 PHP
利用php获得flv视频长度的实例代码
2017/10/26 PHP
js 可拖动列表实现代码
2011/12/13 Javascript
javascript测试题练习代码
2012/10/10 Javascript
jquery删除数据记录时的弹出提示效果
2014/05/06 Javascript
使用GruntJS构建Web程序之构建篇
2014/06/04 Javascript
jQuery Real Person验证码插件防止表单自动提交
2015/11/06 Javascript
JS全局变量和局部变量最新解析
2016/06/24 Javascript
详解vue表单验证组件 v-verify-plugin
2017/04/19 Javascript
使用Fullpage插件快速开发整屏翻页的页面
2017/09/13 Javascript
jQuery实现的下雪动画效果示例【附源码下载】
2018/02/02 jQuery
JavaScript设计模式之建造者模式实例教程
2018/07/02 Javascript
LayUi使用switch开关,动态的去控制它是否被启用的方法
2019/09/21 Javascript
vue页面切换项目实现转场动画的方法
2019/11/12 Javascript
[26:52]LGD vs EG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python实现二叉堆
2016/02/03 Python
Python 使用os.remove删除文件夹时报错的解决方法
2017/01/13 Python
PyCharm代码回滚,恢复历史版本的解决方法
2018/10/22 Python
python线程中的同步问题及解决方法
2019/08/29 Python
django实现模型字段动态choice的操作
2020/04/01 Python
Python3如何在服务器打印资产信息
2020/08/27 Python
HTML5 Geolocation API的正确使用方法
2018/12/04 HTML / CSS
DHC中国官方购物网站:日本通信销售No.1化妆品
2016/08/20 全球购物
好莱坞百老汇御用王牌美妆:Koh Gen Do 江原道
2018/04/03 全球购物
密封类可以有虚函数吗
2014/08/11 面试题
英语专业学生个人求职信
2014/01/28 职场文书
《夸父追日》教学反思
2014/02/26 职场文书
青年文明号创建承诺
2014/03/31 职场文书
4S店收银员岗位职责
2015/04/07 职场文书
2016中秋节月饼促销广告语
2016/01/28 职场文书
python 中的jieba分词库
2021/11/23 Python
Win11远程连接不上怎么办?Win11远程桌面用不了的解决方法
2022/08/05 数码科技