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计算圆周长、面积、球体体积并画出圆
Apr 08 Python
Python3基础之输入和输出实例分析
Aug 18 Python
Python编写电话薄实现增删改查功能
May 07 Python
python编程通过蒙特卡洛法计算定积分详解
Dec 13 Python
Python实现动态图解析、合成与倒放
Jan 18 Python
详解Appium+Python之生成html测试报告
Jan 04 Python
python flask几分钟实现web服务的例子
Jul 26 Python
Python 多线程其他属性以及继承Thread类详解
Aug 28 Python
Python lxml模块的基本使用方法分析
Dec 21 Python
Python 日期的转换及计算的具体使用详解
Jan 16 Python
Python3.7在anaconda里面使用IDLE编译器的步骤详解
Apr 29 Python
filter使用python3代码进行迭代元素的实例详解
Dec 03 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连接Oracle for NT 远程数据库
2006/10/09 PHP
input file获得文件根目录简单实现
2013/04/26 PHP
javascript 打印内容方法小结
2009/11/04 Javascript
jquery 分页控件实现代码
2009/11/30 Javascript
Jquery下的26个实用小技巧(jQuery tips, tricks & solutions)
2010/03/01 Javascript
window.addEventListener来解决让一个js事件执行多个函数
2012/12/26 Javascript
js关于精确计算和数值格式化以及直接引js文件
2014/01/28 Javascript
JS图像无缝滚动脚本非常好用
2014/02/10 Javascript
js采用concat和sort将N个数组拼接起来的方法
2016/01/21 Javascript
bootstrap datetimepicker 日期插件在火狐下出现一条报错信息的原因分析及解决办法
2017/03/08 Javascript
js实现Tab选项卡切换效果
2020/07/17 Javascript
node.js学习笔记之koa框架和简单爬虫练习
2018/12/13 Javascript
详解如何模拟实现node中的Events模块(通俗易懂版)
2019/04/15 Javascript
React中Ref 的使用方法详解
2020/04/28 Javascript
js+h5 canvas实现图片验证码
2020/10/11 Javascript
[36:52]DOTA2真视界:基辅特锦赛总决赛
2017/05/21 DOTA
下载糗事百科的内容_python版
2008/12/07 Python
python多线程threading.Lock锁用法实例
2014/11/01 Python
在Python中调用ggplot的三种方法
2015/04/08 Python
Python 3实战爬虫之爬取京东图书的图片详解
2017/10/09 Python
高质量Python代码编写的5个优化技巧
2017/11/16 Python
Python实现将json文件中向量写入Excel的方法
2018/03/26 Python
Python设计模式之观察者模式原理与用法详解
2019/01/16 Python
通过python改变图片特定区域的颜色详解
2019/07/15 Python
Python环境Pillow( PIL )图像处理工具使用解析
2019/09/12 Python
Python3实现发送邮件和发送短信验证码功能
2020/01/07 Python
如何用python爬取微博热搜数据并保存
2021/02/20 Python
户外活动策划方案
2014/03/12 职场文书
养成教育经验材料
2014/05/26 职场文书
农业局党的群众路线教育实践活动整改方案
2014/09/20 职场文书
毕业论文致谢词
2015/05/14 职场文书
掌握一个领域知识,高效学习必备方法
2019/08/08 职场文书
网络新闻该怎么写?这些写作技巧你都知道吗?
2019/08/26 职场文书
死磕 java同步系列之synchronized解析
2021/06/28 Java/Android
MySQL中存储时间的最佳实践指南
2021/07/01 MySQL
MySQL面试题讲解之如何设置Hash索引
2021/11/01 MySQL