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装饰器在Django框架下去除冗余代码的教程
Apr 16 Python
简介Python中用于处理字符串的center()方法
May 18 Python
Swift 3.0在集合类数据结构上的一些新变化总结
Jul 11 Python
Python网络爬虫出现乱码问题的解决方法
Jan 05 Python
Python简单的制作图片验证码实例
May 31 Python
在Python web中实现验证码图片代码分享
Nov 09 Python
python+opencv打开摄像头,保存视频、拍照功能的实现方法
Jan 08 Python
Python的log日志功能及设置方法
Jul 11 Python
python 实现Flask中返回图片流给前端展示
Jan 09 Python
Python 动态变量名定义与调用方法
Feb 09 Python
django 扩展user用户字段inlines方式
Mar 30 Python
Tensorflow安装问题: Could not find a version that satisfies the requirement tensorflow
Apr 20 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
Laravel Eloquent ORM 实现查询表中指定的字段
2019/10/17 PHP
javascript 设置某DIV区域内的checkbox复选框
2009/11/30 Javascript
javascript各浏览器中option元素的表现差异
2011/04/07 Javascript
JS实现简单的顶部定时关闭层效果
2014/06/15 Javascript
js+csss实现的一个带复选框的下拉框
2014/09/29 Javascript
js实现简单div拖拽功能实例
2015/05/12 Javascript
js实现的简单图片浮动效果完整实例
2016/05/10 Javascript
angularjs封装bootstrap时间插件datetimepicker
2016/06/20 Javascript
轻松掌握JavaScript单例模式
2016/08/25 Javascript
vue 中自定义指令改变data中的值
2017/06/02 Javascript
详解用vue.js和laravel实现微信支付
2017/06/23 Javascript
vue用Object.defineProperty手写一个简单的双向绑定的示例
2018/07/09 Javascript
Vue slot用法(小结)
2018/10/22 Javascript
微信小程序 导入图标实现过程详解
2019/10/11 Javascript
vue的hash值原理也是table切换实例代码
2020/12/14 Vue.js
[01:06:43]完美世界DOTA2联赛PWL S3 PXG vs GXR 第二场 12.19
2020/12/24 DOTA
整理Python 常用string函数(收藏)
2016/05/30 Python
Windows下的Jupyter Notebook 安装与自定义启动(图文详解)
2018/02/21 Python
Python爬取数据并写入MySQL数据库的实例
2018/06/21 Python
TensorFlow 合并/连接数组的方法
2018/07/27 Python
python实现AES加密与解密
2019/03/28 Python
通过python实现随机交换礼物程序详解
2019/07/10 Python
Python如何通过百度翻译API实现翻译功能
2020/04/02 Python
python飞机大战游戏实例讲解
2020/12/04 Python
Python列表元素删除和remove()方法详解
2021/01/04 Python
美国体育用品商店:Academy Sports + Outdoors
2020/01/04 全球购物
廉政教育心得体会
2014/01/01 职场文书
毕业生自荐信如何写
2014/03/24 职场文书
小学生禁毒教育心得体会
2016/01/15 职场文书
python 通过使用Yolact训练数据集
2021/04/06 Python
GoLang中生成UUID唯一标识的实现
2021/05/08 Golang
十大最强岩石系宝可梦,怪颚龙实力最强,第七破坏力很强
2022/03/18 日漫
十大好看的穿越动漫排名:《瑞克和莫蒂》第一,国漫《有药》在榜
2022/03/18 日漫
Python Numpy库的超详细教程
2022/04/06 Python
关于对TypeScript泛型参数的默认值理解
2022/07/15 Javascript