简单上手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天气预报采集器实现代码(网页爬虫)
Oct 07 Python
Python实现从URL地址提取文件名的方法
May 15 Python
Python数组定义方法
Apr 13 Python
Python用 KNN 进行验证码识别的实现方法
Feb 06 Python
Pycharm 设置自定义背景颜色的图文教程
May 23 Python
对python当中不在本路径的py文件的引用详解
Dec 15 Python
Python获取、格式化当前时间日期的方法
Feb 10 Python
解决运行出现'dict' object has no attribute 'has_key'问题
Jul 15 Python
vscode调试django项目的方法
Aug 06 Python
Python类成员继承重写的实现
Sep 16 Python
详解scrapy内置中间件的顺序
Sep 28 Python
matplotlib之pyplot模块实现添加子图subplot的使用
Apr 25 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
DOTA2 探索永无止境 玩家自创强悍插眼攻略
2020/04/20 DOTA
PHP迭代器实现斐波纳契数列的函数
2013/11/12 PHP
Yii视图CGridView实现操作按钮定义地址示例
2016/07/14 PHP
JavaScript高级程序设计(第3版)学习笔记2 js基础语法
2012/10/11 Javascript
非常好用的JsonToString 方法 简单实例
2013/07/18 Javascript
用jquery中插件dialog实现弹框效果实例代码
2013/11/15 Javascript
js文本框输入点回车触发确定兼容IE、FF等
2013/11/19 Javascript
jquery图形密码实现方法
2015/03/11 Javascript
微信小程序canvas写字板效果及实例
2017/06/15 Javascript
史上最全JavaScript数组去重的十种方法(推荐)
2017/08/17 Javascript
node中modules.exports与exports导出的区别
2018/06/08 Javascript
jQuery实现炫丽的3d旋转星空效果
2018/07/04 jQuery
[01:07:22]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG加赛
2014/05/26 DOTA
Python中itertools模块用法详解
2014/09/25 Python
python并发编程之多进程、多线程、异步和协程详解
2016/10/28 Python
Python验证文件是否可读写代码分享
2017/12/11 Python
详解Python下Flask-ApScheduler快速指南
2018/11/04 Python
pymongo中group by的操作方法教程
2019/03/22 Python
Python动态语言与鸭子类型详解
2019/07/01 Python
pybind11在Windows下的使用教程
2019/07/04 Python
使用 pytorch 创建神经网络拟合sin函数的实现
2020/02/24 Python
css3 响应式媒体查询的示例代码
2019/09/25 HTML / CSS
StubHub美国:购买或出售您的门票
2019/07/09 全球购物
聚美优品励志广告词
2014/03/14 职场文书
春节联欢晚会主持词范文
2014/03/24 职场文书
副职竞争上岗演讲稿
2014/05/12 职场文书
民事诉讼代理委托书
2014/10/08 职场文书
2014年生产部工作总结
2014/12/17 职场文书
装修公司工程部经理岗位职责
2015/04/09 职场文书
妈妈再爱我一次观后感
2015/06/08 职场文书
公司管理建议书
2015/09/14 职场文书
2016医师资格考试考生诚信考试承诺书
2016/03/25 职场文书
假期读书倡议书3篇
2019/08/19 职场文书
创业计划书之都市休闲农庄
2019/12/28 职场文书
关于Python中*args和**kwargs的深入理解
2021/08/07 Python
nginx搭建NFS网络文件系统
2022/04/14 Servers