简单理解Python中的装饰器


Posted in Python onJuly 31, 2015

Python的装饰器可以实现在代码运行期间修改函数的上下文, 即可以定义函数在执行之前进行何种操作和函数执行后进行何种操作, 而函数本身并没有任何的改变。

首先, 我们先定义一个函数, 这个函数可以输出我的个人昵称:

def my_name():
  print "Yi_Zhi_Yu"
my_name() # Yi_Zhi_Yu

那假如我需要在个人昵称输出前, 在输出我的个人uid呢, 当然, 要求是不改动现有的my_name函数, 这个时候就可以使用装饰器了

首先, 装饰器也是个函数, 其次, 他需要接受一个参数,该参数表示了要被装饰的函数(即my_name):

def my_info(func):
  def wrapper(*args, **params):
    print 218
    return func(*args, **params)
  return wrapper

然后与相应的被装饰函数关联起来的方法就是使用@my_info写在被装饰函数的前面

@my_info
def my_name():
  print "Yi_Zhi_Yu"

最后, 在执行my_name的时候, 就能既输出我的uid, 又能输出我的昵称了

my_name()
#218
#Yi_Zhi_Yu

在上面, 最让我们疑惑的是装饰器函数定义里面的wrapper函数, 装饰器本身返回的是wrapper函数的定义, 而wrapper中则定义了对被装饰函数(my_name)的调用, func表示的就是被装饰函数, 说白了, 装饰器只是把某个不得改动的函数(a)放到另一个函数(b)中, 在b里面调用a, 在调用前后就可以做所谓的看起来像装饰的工作了。
my_info的最终返回的wrapper函数的定义, 并不是执行结果,只有当wrapper真正执行的时候, 才会真正的执行my_name方法, 这就是闭包时所说的内容。
wrapper中的参数, 实际上则是传递给func(实际上是my_name)的参数

因为装饰器也是个函数, 那么装饰器自己的能不能有参数传递呢。可以, 不过需要定义一个更高阶的函数, 也就是外面还要套一层函数, 比如, 我还要输出我的自定义的一个信息,需要传递参数

def c_info(text):
  def my_info(func):
    def wrapper(*args, **params):
      print text
      print 218
      return func(*args, **params)
    return wrapper
  return my_info
#使用装饰器

@c_info("Tony")
 def my_name():
  print "Yi_Zhi_Yu"

 my_name()
 #Tony
 #218
 #Yi_Zhi_Yu

与前面的那个装饰器相比, 仅仅是多了个外层, 内层也仅仅是增加了对外层传入参数(text)的调用

总而言之, Python在函数定义中支持了对oop思想中的装饰器的实现, 其本质也只是使用了闭包的思路, 延迟调用, 并在调用前后增加自己的其他实现内容

Ps: 以上皆为学习笔记, 附带自己的理解, 难免有偏差, 如有发现纰漏, 还望指正

Python 相关文章推荐
Python和GO语言实现的消息摘要算法示例
Mar 10 Python
Flask入门教程实例:搭建一个静态博客
Mar 27 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
Nov 30 Python
python 检查文件mime类型的方法
Dec 08 Python
Python常用特殊方法实例总结
Mar 22 Python
python [:3] 实现提取数组中的数
Nov 27 Python
在 Linux/Mac 下为Python函数添加超时时间的方法
Feb 20 Python
python 操作mysql数据中fetchone()和fetchall()方式
May 15 Python
tensorflow实现从.ckpt文件中读取任意变量
May 26 Python
python中 _、__、__xx__()区别及使用场景
Jun 30 Python
使用Selenium实现微博爬虫(预登录、展开全文、翻页)
Apr 13 Python
浅谈Python从全局与局部变量到装饰器的相关知识
Jun 21 Python
python简单分割文件的方法
Jul 30 #Python
Python读取网页内容的方法
Jul 30 #Python
python查看FTP是否能连接成功的方法
Jul 30 #Python
python如何实现excel数据添加到mongodb
Jul 30 #Python
python学习之第三方包安装方法(两种方法)
Jul 30 #Python
Python实现的Excel文件读写类
Jul 30 #Python
Djang中静态文件配置方法
Jul 30 #Python
You might like
JavaScript中json使用自己总结
2013/08/13 Javascript
js 浏览本地文件夹系统示例代码
2013/10/24 Javascript
javascript怎么禁用浏览器后退按钮
2014/03/27 Javascript
JavaScript多图片上传案例
2015/09/28 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
JavaScript中数组的22种方法必学(推荐)
2016/07/20 Javascript
JSON字符串和JSON对象相互转化实例详解
2017/01/05 Javascript
AugularJS从入门到实践(必看篇)
2017/07/10 Javascript
react中实现搜索结果中关键词高亮显示
2018/07/31 Javascript
vue将毫秒数转化为正常日期格式的实例
2018/09/16 Javascript
vscode下vue项目中eslint的使用方法
2019/01/13 Javascript
JavaScript随机数的组合问题案例分析
2020/05/16 Javascript
vue实现一个6个输入框的验证码输入组件功能的实例代码
2020/06/29 Javascript
在vs code 中如何创建一个自己的 Vue 模板代码
2020/11/10 Javascript
python中Flask框架简单入门实例
2015/03/21 Python
详解Python中time()方法的使用的教程
2015/05/22 Python
python提取字典key列表的方法
2015/07/11 Python
详解supervisor使用教程
2017/11/21 Python
python实现zabbix发送短信脚本
2018/09/17 Python
Python 求数组局部最大值的实例
2019/11/26 Python
python collections模块的使用
2020/10/16 Python
python实现文件+参数发送request的实例代码
2021/01/05 Python
Python3.9.1中使用split()的处理方法(推荐)
2021/02/07 Python
Python Selenium操作Cookie的实例方法
2021/02/28 Python
实例教程 一款纯css3实现的数字统计游戏
2014/11/10 HTML / CSS
Desigual英国官网:在线购买原创服装
2018/03/09 全球购物
工商管理实习自我鉴定
2013/09/28 职场文书
师范生自荐信范文
2013/10/06 职场文书
工业自动化专业自荐信范文
2014/04/10 职场文书
小学德育工作经验交流材料
2014/05/22 职场文书
汽车检测与维修专业求职信
2014/07/04 职场文书
室内趣味活动方案
2014/08/24 职场文书
商业门面租房协议书
2014/11/25 职场文书
2014年幼儿园学期工作总结
2014/12/05 职场文书
服务员岗位职责
2015/02/03 职场文书
SpringBoot SpringEL表达式的使用
2021/07/25 Java/Android