简单上手Python中装饰器的使用


Posted in Python onJuly 12, 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思想中的装饰器的实现, 其本质也只是使用了闭包的思路, 延迟调用, 并在调用前后增加自己的其他实现内容

Python 相关文章推荐
python基础入门详解(文件输入/输出 内建类型 字典操作使用方法)
Dec 08 Python
python实现DNS正向查询、反向查询的例子
Apr 25 Python
python+selenium实现京东自动登录及秒杀功能
Nov 18 Python
python编写朴素贝叶斯用于文本分类
Dec 21 Python
Python简单实现网页内容抓取功能示例
Jun 07 Python
解决DataFrame排序sort的问题
Jun 07 Python
在Python中增加和插入元素的示例
Nov 01 Python
python 消除 futureWarning问题的解决
Dec 25 Python
解决pyPdf和pyPdf2在合并pdf时出现异常的问题
Apr 03 Python
基于python实现matlab filter函数过程详解
Jun 08 Python
keras实现调用自己训练的模型,并去掉全连接层
Jun 09 Python
如何基于python把文字图片写入word文档
Jul 31 Python
python比较两个列表大小的方法
Jul 11 #Python
python实现计算倒数的方法
Jul 11 #Python
python实现基本进制转换的方法
Jul 11 #Python
python计算圆周率pi的方法
Jul 11 #Python
python计算一个序列的平均值的方法
Jul 11 #Python
python修改字典内key对应值的方法
Jul 11 #Python
python字典基本操作实例分析
Jul 11 #Python
You might like
php网站被挂木马后的修复方法总结
2014/11/06 PHP
PHP 返回13位时间戳的实现代码
2016/05/13 PHP
PHP解决中文乱码
2017/04/28 PHP
Laravel程序架构设计思路之使用动作类
2018/06/07 PHP
PHP从零开始打造自己的MVC框架之类的自动加载实现方法详解
2019/06/03 PHP
Javascript this关键字使用分析
2008/10/21 Javascript
常用简易JavaScript函数
2009/04/09 Javascript
JavaScript 页面编码与浏览器类型判断代码
2010/06/03 Javascript
jquery下onpropertychange事件的绑定方法
2010/08/01 Javascript
jquery教程限制文本框只能输入数字和小数点示例分享
2014/01/13 Javascript
js实现按一下删除键删除整个单词附demo
2014/09/05 Javascript
jQuery对象的selector属性用法实例
2014/12/27 Javascript
NodeJS学习笔记之Connect中间件模块(二)
2015/01/27 NodeJs
JS基于面向对象实现的选项卡效果示例
2016/12/20 Javascript
JS轮播图中缓动函数的封装
2020/11/25 Javascript
JS实现向iframe中表单传值的方法
2017/03/24 Javascript
Bootstrap响应式导航由768px变成992px的实现代码
2017/06/15 Javascript
解决vue点击控制单个样式的问题
2018/09/05 Javascript
vuejs router history 配置到iis的方法
2018/09/20 Javascript
基于vue和react的spa进行按需加载的实现方法
2018/09/29 Javascript
JS 数组和对象的深拷贝操作示例
2020/06/06 Javascript
微信小程序实现简单购物车功能
2020/12/30 Javascript
Python中使用logging和traceback模块记录日志和跟踪异常
2019/04/09 Python
face++与python实现人脸识别签到(考勤)功能
2019/08/28 Python
python3.8 微信发送服务器监控报警消息代码实现
2019/11/05 Python
Python计算机视觉里的IOU计算实例
2020/01/17 Python
django在开发中取消外键约束的实现
2020/05/20 Python
全球虚拟主机商:HostGator
2017/02/06 全球购物
英国图书音像网站:Hive.co.uk(图书、电子书、DVD、蓝光、音乐CD等)
2017/10/16 全球购物
365 Tickets英国:全球景点门票
2019/07/06 全球购物
公司人力资源的自我评价
2014/01/02 职场文书
小学生环保倡议书
2014/05/15 职场文书
2015年社区工会工作总结
2015/05/26 职场文书
教师节主题班会方案
2015/08/17 职场文书
Python实现批量自动整理文件
2022/03/16 Python
python疲劳驾驶困倦低头检测功能的实现
2022/04/04 Python