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实现截屏的函数
Jul 26 Python
浅谈Python单向链表的实现
Dec 24 Python
Django 添加静态文件的两种实现方法(必看篇)
Jul 14 Python
python爬虫中get和post方法介绍以及cookie作用
Feb 08 Python
Python针对给定字符串求解所有子序列是否为回文序列的方法
Apr 21 Python
python适合人工智能的理由和优势
Jun 28 Python
关于Python内存分配时的小秘密分享
Sep 05 Python
python web框架中实现原生分页
Sep 08 Python
Django使用Profile扩展User模块方式
May 14 Python
Opencv图像处理:如何判断图片里某个颜色值占的比例
Jun 03 Python
python实现数字炸弹游戏程序
Jul 17 Python
python3中for循环踩过的坑记录
Dec 14 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调用Java对象的方法
2006/10/09 PHP
php源代码安装常见错误与解决办法分享
2013/05/28 PHP
在TP5数据库中四个字段实现无限分类的示例
2019/10/18 PHP
Javascript 文件夹选择框的两种解决方案
2009/07/01 Javascript
ExtJs GridPanel简单的增删改实现代码
2010/08/26 Javascript
JavaScript对象创建及继承原理实例解剖
2013/02/28 Javascript
JS截取字符串常用方法详细整理
2013/10/28 Javascript
基于jquery固定于顶部的导航响应浏览器滚动条事件
2014/11/02 Javascript
nodejs批量修改文件编码格式
2015/01/22 NodeJs
jquery.validate使用时遇到的问题
2015/05/25 Javascript
js事件监听器用法实例详解
2015/06/01 Javascript
jQuery Easyui 验证两次密码输入是否相等
2016/05/13 Javascript
详解JavaScript中return的用法
2017/05/08 Javascript
学习使用Bootstrap栅格系统
2017/05/11 Javascript
javascript 跨域问题以及解决办法
2017/07/17 Javascript
jQuery实现手势解锁密码特效
2017/08/14 jQuery
微信小程序视图template模板引用的实例详解
2017/09/20 Javascript
vue自定义指令的创建和使用方法实例分析
2018/12/04 Javascript
JS集合set类的实现与使用方法示例
2019/02/01 Javascript
python类和函数中使用静态变量的方法
2015/05/09 Python
Python3实现从指定路径查找文件的方法
2015/05/22 Python
Python使用pandas对数据进行差分运算的方法
2018/12/22 Python
python多线程下信号处理程序示例
2019/05/31 Python
Python实现的ftp服务器功能详解【附源码下载】
2019/06/26 Python
使用 Python 快速实现 HTTP 和 FTP 服务器的方法
2019/07/22 Python
Python 实现一个手机号码获取妹子名字的功能
2019/09/25 Python
python的help函数如何使用
2020/06/11 Python
Pycharm Git 设置方法
2020/09/15 Python
销售所有的狗狗产品:Dog.com
2016/10/13 全球购物
美国伴娘礼服商店:Evening Collective
2019/10/07 全球购物
Carmen Sol官网:购买果冻鞋、手袋和配件
2021/01/01 全球购物
旷课检讨书大全
2014/01/21 职场文书
致铅球运动员加油稿
2014/02/13 职场文书
大学生未来职业生涯规划书
2014/02/15 职场文书
计划生育证明书写要求
2014/09/17 职场文书
2014年教师思想工作总结
2014/12/03 职场文书