简单理解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获得文件创建时间和修改时间的方法
Jun 30 Python
利用Python进行异常值分析实例代码
Dec 07 Python
python网络爬虫学习笔记(1)
Apr 09 Python
tensorflow实现图像的裁剪和填充方法
Jul 27 Python
解决python线程卡死的问题
Feb 18 Python
PyQt5实现简易计算器
May 30 Python
Django自定义模板过滤器和标签的实现方法
Aug 21 Python
tensorflow 环境变量设置方式
Feb 06 Python
Keras 快速解决OOM超内存的问题
Jun 11 Python
python 利用Pyinstaller打包Web项目
Oct 23 Python
Python中读取文件名中的数字的实例详解
Dec 25 Python
教你怎么用Python处理excel实现自动化办公
Apr 30 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
如何在PHP程序中防止盗链
2008/04/09 PHP
php全排列递归算法代码
2012/10/09 PHP
php session劫持和防范的方法
2013/11/12 PHP
php+redis消息队列实现抢购功能
2018/02/08 PHP
学习YUI.Ext 第三天
2007/03/10 Javascript
js获取RadioButtonList的Value/Text及选中值等信息实现代码
2013/03/05 Javascript
如何使用json在前后台进行数据传输实例介绍
2013/04/11 Javascript
js动态创建上传表单通过iframe模拟Ajax实现无刷新
2014/02/20 Javascript
angularJS 中input示例分享
2015/02/09 Javascript
JavaScript对象参数的引用传递
2016/01/14 Javascript
JavaScript数组方法总结分析
2016/05/06 Javascript
javascript三种代码注释方法
2016/06/02 Javascript
JS使用面向对象技术实现的tab选项卡效果示例
2017/02/28 Javascript
JS使用正则表达式验证身份证号码
2017/06/23 Javascript
详解Vue2 添加对scss的支持
2019/01/02 Javascript
JS实现移动端点击按钮复制文本内容
2019/07/28 Javascript
layui在form表单页面通过Validform加入简单验证的方法
2019/09/06 Javascript
使用Vue Composition API写出清晰、可扩展的表单实现
2020/06/10 Javascript
JavaScript实现缓动动画
2020/11/25 Javascript
[01:13]2014DOTA2西雅图邀请赛 舌尖上的TI4
2014/07/08 DOTA
python查询sqlite数据表的方法
2015/05/08 Python
Python+微信接口实现运维报警
2016/08/27 Python
Pandas:Series和DataFrame删除指定轴上数据的方法
2018/11/10 Python
python 重命名轴索引的方法
2018/11/10 Python
Python3离线安装Requests模块问题
2019/10/13 Python
numpy.transpose()实现数组的转置例子
2019/12/02 Python
pytorch实现线性拟合方式
2020/01/15 Python
10个很棒的 CSS3 开发工具 推荐
2011/05/16 HTML / CSS
个人实用简单的自我评价
2013/10/19 职场文书
暑期社会实践学生的自我评价
2014/01/09 职场文书
现金出纳岗位职责
2014/03/15 职场文书
中国梦演讲稿3分钟
2014/08/19 职场文书
普通员工辞职信范文
2015/05/12 职场文书
红楼梦读书笔记
2015/06/25 职场文书
心理健康教育主题班会
2015/08/13 职场文书
《最后一头战象》读后感:动物也有感情
2020/01/02 职场文书