简单上手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根据经纬度计算距离示例
Feb 16 Python
python连接MySQL数据库实例分析
May 12 Python
Python的Tornado框架的异步任务与AsyncHTTPClient
Jun 27 Python
Django自定义分页效果
Jun 27 Python
Python跨文件全局变量的实现方法示例
Dec 10 Python
PyQt实现界面翻转切换效果
Apr 20 Python
Python格式化输出%s和%d
May 07 Python
Python常见数字运算操作实例小结
Mar 22 Python
Python 实现平台类游戏添加跳跃功能
Mar 27 Python
Python垃圾回收机制三种实现方法
Apr 27 Python
python小白学习包管理器pip安装
Jun 09 Python
pandas 实现将NaN转换为None
May 14 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实现简单洗牌算法
2013/06/18 PHP
php对图像的各种处理函数代码小结
2013/07/08 PHP
php简单创建zip压缩文件的方法
2016/04/30 PHP
Laravel 实现密码重置功能
2018/02/23 PHP
Laravel框架中集成MongoDB和使用详解
2019/10/17 PHP
jquery.boxy插件的iframe扩展代码
2010/07/02 Javascript
jquery中防刷IP流量软件影响统计的一点对策
2011/07/10 Javascript
php中给js数组赋值方法
2014/03/10 Javascript
使用javascript实现雪花飘落的效果
2015/01/13 Javascript
Javascript递归打印Document层次关系实例分析
2015/05/15 Javascript
利用Angularjs和Bootstrap前端开发案例实战
2016/08/27 Javascript
Node.js操作redis实现添加查询功能
2017/05/25 Javascript
通过命令行创建vue项目的方法
2017/07/20 Javascript
Node.js 使用AngularJS的方法示例
2018/05/11 Javascript
webpack 从指定入口文件中提取公共文件的方法
2018/11/13 Javascript
JavaScript Tab菜单实现过程解析
2020/05/13 Javascript
[01:31](回顾)杀出重围,决战TI之巅
2014/07/01 DOTA
python正则表达式判断字符串是否是全部小写示例
2013/12/25 Python
Python中使用ConfigParser解析ini配置文件实例
2014/08/30 Python
Python随机生成数模块random使用实例
2015/04/13 Python
python实现k-means聚类算法
2018/02/23 Python
python3使用flask编写注册post接口的方法
2018/12/28 Python
python按比例随机切分数据的实现
2019/07/11 Python
Python3中对json格式数据的分析处理
2021/01/28 Python
Python3自带工具2to3.py 转换 Python2.x 代码到Python3的操作
2021/03/03 Python
如何在Canvas中添加事件的方法示例
2019/05/21 HTML / CSS
JAKO-O德国野酷台湾站:德国首屈一指的婴幼童用品品牌
2019/01/14 全球购物
AJax面试题
2014/11/25 面试题
入党申请书自我鉴定
2013/10/12 职场文书
大学毕业生简单自荐信
2013/11/05 职场文书
信息技术专业大学生职业生涯规划书
2014/01/24 职场文书
运动会入场词60字
2014/02/15 职场文书
2014年党建工作总结
2014/11/11 职场文书
高校自主招生教师推荐信
2015/03/23 职场文书
欠条范文
2015/07/03 职场文书
html中显示特殊符号(附带特殊字符对应表)
2021/06/21 HTML / CSS