简单上手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 获取Android设备信息的轻量级框架
Dec 18 Python
Python数据结构之双向链表的定义与使用方法示例
Jan 16 Python
Python爬虫设置代理IP的方法(爬虫技巧)
Mar 04 Python
使用Python编写Prometheus监控的方法
Oct 15 Python
破解安装Pycharm的方法
Oct 19 Python
在pycharm 中添加运行参数的操作方法
Jan 19 Python
python 格式化输出百分号的方法
Jan 20 Python
Python代码太长换行的实现
Jul 05 Python
python实现的登录与提交表单数据功能示例
Sep 25 Python
pytorch中tensor.expand()和tensor.expand_as()函数详解
Dec 27 Python
Python3打包exe代码2种方法实例解析
Feb 17 Python
Python find()、rfind()方法及作用
Dec 24 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对象转换为数组函数(递归方法)
2012/02/04 PHP
php设计模式之简单工厂模式详解
2014/09/04 PHP
php中异常处理方法小结
2015/01/09 PHP
php对关联数组循环遍历的实现方法
2015/03/13 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
PHPTree――php快速生成无限级分类
2018/03/30 PHP
Javascript 面试题随笔
2011/03/31 Javascript
jquery插件如何使用 jQuery操作Cookie插件使用介绍
2012/12/15 Javascript
JS localStorage实现本地缓存的方法
2013/06/22 Javascript
JS按字节截取字符长度实例
2013/11/20 Javascript
jquery模拟多级复选框效果的简单实例
2016/06/08 Javascript
jqPlot jQuery绘图插件的使用
2016/06/18 Javascript
详解js中Json的语法与格式
2016/11/22 Javascript
ES2020 新特性(种草)
2020/01/12 Javascript
vue 使用插槽分发内容操作示例【单个插槽、具名插槽、作用域插槽】
2020/03/06 Javascript
微信小程序将页面按钮悬浮固定在底部的实现代码
2020/10/29 Javascript
python win32 简单操作方法
2017/05/25 Python
python逆向入门教程
2018/01/15 Python
如何利用Python开发一个简单的猜数字游戏
2019/09/22 Python
使用python代码进行身份证号校验的实现示例
2019/11/21 Python
Python如何实现强制数据类型转换
2019/11/22 Python
用python拟合等角螺线的实现示例
2019/12/27 Python
Python基于Dlib的人脸识别系统的实现
2020/02/26 Python
python实现猜拳游戏
2020/03/04 Python
Python装饰器用法与知识点小结
2020/03/09 Python
VSCode基础使用与VSCode调试python程序入门的图文教程
2020/03/30 Python
TensorFlow固化模型的实现操作
2020/05/26 Python
python使用re模块爬取豆瓣Top250电影
2020/10/20 Python
生日宴会答谢词
2014/01/09 职场文书
大学同学聚会邀请函
2014/01/19 职场文书
八荣八耻的活动方案
2014/08/16 职场文书
临时工聘用合同协议书
2014/10/29 职场文书
初中优秀学生评语
2014/12/29 职场文书
高中生综合素质自我评价
2015/03/06 职场文书
个人自荐书怎么写
2015/03/26 职场文书
八一建军节主持词
2015/07/01 职场文书