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 09 Python
通过数据库向Django模型添加字段的示例
Jul 21 Python
Python常用知识点汇总
May 08 Python
实践Vim配置python开发环境
Jul 02 Python
带你认识Django
Jan 15 Python
使用PyTorch训练一个图像分类器实例
Jan 08 Python
python 函数中的参数类型
Feb 11 Python
使用Python将Exception异常错误堆栈信息写入日志文件
Apr 08 Python
keras实现多GPU或指定GPU的使用介绍
Jun 17 Python
Python selenium如何打包静态网页并下载
Aug 12 Python
怎么解决pycharm license Acti的方法
Oct 28 Python
python中subplot大小的设置步骤
Jun 28 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学习散记_编码(json_encode 中文不显示)
2011/11/10 PHP
PHP 清空varnish 缓存的详解(包括指定站点下的)
2013/06/20 PHP
PHP提示Deprecated: mysql_connect(): The mysql extension is deprecated的解决方法
2014/08/28 PHP
6个超实用的PHP代码片段
2015/08/10 PHP
详解YII关联查询
2016/01/10 PHP
Jquery Ajax的Get方式时需要注意URL地方
2011/04/07 Javascript
JS实现定时页面弹出类似QQ新闻的提示框
2013/11/07 Javascript
window.open打开页面居中显示的示例代码
2013/12/27 Javascript
Bootstrap3使用typeahead插件实现自动补全功能
2016/07/07 Javascript
微信小程序实现倒计时调用相机自动拍照功能
2018/06/10 Javascript
vue自定义移动端touch事件之点击、滑动、长按事件
2018/07/10 Javascript
Vue 实现展开折叠效果的示例代码
2018/08/27 Javascript
npm 语义版本控制详解
2019/09/10 Javascript
js实现金山打字通小游戏
2020/07/24 Javascript
vue+element-ui JYAdmin后台管理系统模板解析
2020/07/28 Javascript
JS中箭头函数与this的写法和理解
2021/01/14 Javascript
Python多进程分块读取超大文件的方法
2016/04/13 Python
python 文件操作api(文件操作函数)
2016/08/28 Python
python处理按钮消息的实例详解
2017/07/11 Python
python实现音乐下载器
2018/04/15 Python
基于python if 判断选择结构的实例详解
2019/05/06 Python
Python键鼠操作自动化库PyAutoGUI简介(小结)
2020/05/17 Python
Django自带的用户验证系统实现
2020/12/18 Python
新西兰最大的在线设计师眼镜店:SmartBuyGlasses新西兰
2017/10/20 全球购物
AOP的定义以及作用
2013/09/08 面试题
公司联欢晚会主持词
2014/03/22 职场文书
颁奖典礼主持词
2014/03/25 职场文书
服务宗旨标语
2014/07/01 职场文书
调研汇报材料范文
2014/08/17 职场文书
小学生三分钟演讲稿
2014/08/18 职场文书
幼儿园感谢信
2015/01/21 职场文书
自愿离婚协议书范本
2015/01/26 职场文书
三年级作文之趣事作文
2019/11/04 职场文书
在python中实现导入一个需要传参的模块
2021/05/12 Python
使用 Apache Superset 可视化 ClickHouse 数据的两种方法
2021/07/07 Servers
MySQL窗口函数的具体使用
2021/11/17 MySQL