简单理解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如何实现MySQL实例初始化详解
Nov 06 Python
django实现用户登陆功能详解
Dec 11 Python
python读取视频流提取视频帧的两种方法
Oct 22 Python
对Python中range()函数和list的比较
Apr 19 Python
python 中字典嵌套列表的方法
Jul 03 Python
Python使用微信itchat接口实现查看自己微信的信息功能详解
Aug 22 Python
Python模拟登录之滑块验证码的破解(实例代码)
Nov 18 Python
python 浅谈serial与stm32通信的编码问题
Dec 18 Python
无惧面试,带你搞懂python 装饰器
Aug 17 Python
详解Pycharm第三方库的安装及使用方法
Dec 29 Python
详解Python调用系统命令的六种方法
Jan 28 Python
Python pandas之求和运算和非空值个数统计
Aug 07 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中的闭包和匿名函数
2017/12/25 PHP
js jquery做的图片连续滚动代码
2008/01/06 Javascript
jQuery 自定义函数写法分享
2012/03/30 Javascript
基于IE下ul li 互相嵌套时的bug,排查,解决过程以及心得介绍
2013/05/07 Javascript
jquery自定义类似$.ajax()的方法实现代码
2013/08/13 Javascript
js点击出现悬浮窗效果不使用JQuery插件
2014/01/20 Javascript
Jquery 垂直多级手风琴菜单附源码下载
2015/11/17 Javascript
jquery实现表格隔行换色效果
2015/11/19 Javascript
第九章之路径分页标签与徽章组件
2016/04/25 Javascript
第三篇Bootstrap网格基础
2016/06/21 Javascript
本地搭建微信小程序服务器的实现方法
2017/10/27 Javascript
Vue.use源码学习小结
2018/06/20 Javascript
解决vue attr取不到属性值的问题
2018/09/18 Javascript
微信小程序冒泡事件及其阻止方法实例分析
2018/12/06 Javascript
HTML元素拖拽功能实现的完整实例
2020/12/04 Javascript
python执行子进程实现进程间通信的方法
2015/06/02 Python
python实现下载指定网址所有图片的方法
2015/08/08 Python
python3写爬取B站视频弹幕功能
2017/12/22 Python
python实现堆和索引堆的代码示例
2018/03/19 Python
python交互模式下输入换行/输入多行命令的方法
2019/07/02 Python
python3文件复制、延迟文件复制任务的实现方法
2019/09/02 Python
利用python计算时间差(返回天数)
2019/09/07 Python
Anaconda的安装与虚拟环境建立
2020/11/18 Python
用CSS3和table标签实现一个圆形轨迹的动画的示例代码
2019/01/17 HTML / CSS
CSS3实现酷炫的3D旋转透视效果
2019/11/21 HTML / CSS
白色公司:The White Company
2017/10/11 全球购物
《在大海中永生》教学反思
2014/02/24 职场文书
蓝颜请假条
2014/04/11 职场文书
学习考察心得体会
2014/09/04 职场文书
社保代办委托书怎么写
2014/10/06 职场文书
大学升旗仪式主持词
2015/07/04 职场文书
大学学生会主席竞选稿
2015/11/19 职场文书
如何制作自己的原生JavaScript路由
2021/05/05 Javascript
tensorflow中的数据类型dtype用法说明
2021/05/26 Python
Oracle 临时表空间SQL语句的实现
2021/09/25 Oracle
MySQL数据库索引的最左匹配原则
2021/11/20 MySQL