简单理解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 pass 语句使用示例
Mar 11 Python
Python和perl实现批量对目录下电子书文件重命名的代码分享
Nov 21 Python
浅谈python 里面的单下划线与双下划线的区别
Dec 01 Python
Python基于列表模拟堆栈和队列功能示例
Jan 05 Python
python编辑用户登入界面的实现代码
Jul 16 Python
详解如何在Apache中运行Python WSGI应用
Jan 02 Python
解决python 文本过滤和清理问题
Aug 28 Python
Django之使用内置函数和celery发邮件的方法示例
Sep 16 Python
pandas 中对特征进行硬编码和onehot编码的实现
Dec 20 Python
如何基于windows实现python定时爬虫
May 01 Python
Python socket服务常用操作代码实例
Jun 22 Python
python批量合成bilibili的m4s缓存文件为MP4格式 ver2.5
Dec 01 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
新的一年,新的期待:DC在2020年的四部动画电影
2020/01/01 欧美动漫
php下删除一篇文章生成的多个静态页面
2010/08/08 PHP
检测png图片是否完整的php代码
2010/09/06 PHP
Yii中render和renderPartial的区别
2014/09/03 PHP
Nginx下ThinkPHP5的配置方法详解
2017/08/01 PHP
php 实现简单的登录功能示例【基于thinkPHP框架】
2019/12/02 PHP
javascript 函数速查表
2010/02/07 Javascript
利用try-catch判断变量是已声明未声明还是未赋值
2014/03/12 Javascript
JavaScript输出当前时间Unix时间戳的方法
2015/04/06 Javascript
简单实现兼容各大浏览器的js复制内容到剪切板
2015/09/09 Javascript
七个不允许错过的jQuery小技巧
2015/12/21 Javascript
JS随机洗牌算法之数组随机排序
2016/03/23 Javascript
JS实现改变HTML上文字颜色和内容的方法
2016/12/30 Javascript
详谈jQuery unbind 删除绑定事件 / 移除标签方法
2017/03/02 Javascript
vue-cli webpack2项目打包优化分享
2018/02/07 Javascript
js 图片转base64的方式(两种)
2018/04/24 Javascript
vue中$refs的用法及作用详解
2018/04/24 Javascript
JS面试题中深拷贝的实现讲解
2020/05/07 Javascript
[22:07]DOTA2-DPC中国联赛 正赛 iG vs Magma 选手采访
2021/03/11 DOTA
Python字符串替换实例分析
2015/05/11 Python
以视频爬取实例讲解Python爬虫神器Beautiful Soup用法
2016/01/20 Python
Python实现个人微信号自动监控告警的示例
2019/07/03 Python
利用python list完成最简单的DB连接池方法
2019/08/09 Python
Python发送邮件的实例代码讲解
2019/10/16 Python
使用python-opencv读取视频,计算视频总帧数及FPS的实现
2019/12/10 Python
利用HTML5的新特点实现图片文件异步上传
2014/05/29 HTML / CSS
诗普兰迪官方网站:Splendid
2018/09/18 全球购物
租赁协议书范本
2014/04/22 职场文书
商场周年庆活动方案
2014/08/19 职场文书
关于读书的演讲稿600字
2014/08/27 职场文书
会计岗位工作总结
2015/08/12 职场文书
商业计划书之服装
2019/09/09 职场文书
用 Python 元类的特性实现 ORM 框架
2021/05/19 Python
详解vue身份认证管理和租户管理
2021/05/25 Vue.js
python神经网络学习 使用Keras进行回归运算
2022/05/04 Python
Tomcat 与 maven 的安装与使用教程
2022/06/16 Servers