简单上手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中数据解析
May 05 Python
python实现unicode转中文及转换默认编码的方法
Apr 29 Python
Python使用QRCode模块生成二维码实例详解
Jun 14 Python
使用python在本地电脑上快速处理数据
Jun 22 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
Nov 20 Python
使用python爬虫实现网络股票信息爬取的demo
Jan 05 Python
使用Python写一个量化股票提醒系统
Aug 22 Python
使用Python向DataFrame中指定位置添加一列或多列的方法
Jan 29 Python
pyqt实现.ui文件批量转换为对应.py文件脚本
Jun 19 Python
Pycharm2020最新激活码|永久激活(附最新激活码和插件的详细教程)
Sep 29 Python
Python调用JavaScript代码的方法
Oct 27 Python
python数字类型和占位符详情
Mar 13 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/07/08 PHP
php实现面包屑导航例子分享
2015/12/19 PHP
最新版本PHP 7 vs HHVM 多角度比较
2016/02/14 PHP
php array_merge_recursive 数组合并
2016/10/26 PHP
用nodejs实现PHP的print_r函数代码
2014/03/14 NodeJs
jQuery.prop() 使用详解
2015/07/19 Javascript
JS作用域闭包、预解释和this关键字综合实例解析
2016/12/16 Javascript
Angular的$http的ajax的请求操作(推荐)
2017/01/10 Javascript
浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序
2017/02/19 Javascript
Vue.directive自定义指令的使用详解
2017/03/10 Javascript
微信小程序动态添加view组件的实例代码
2019/05/23 Javascript
在vue中实现某一些路由页面隐藏导航栏的功能操作
2020/09/21 Javascript
ant design 日期格式化的实现
2020/10/27 Javascript
js实现扫雷源代码
2020/11/27 Javascript
[39:46]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第二场 11.25
2020/11/25 DOTA
Python提取Linux内核源代码的目录结构实现方法
2016/06/24 Python
python开发环境PyScripter中文乱码问题解决方案
2016/09/11 Python
基于Python3 逗号代码 和 字符图网格(详谈)
2017/06/22 Python
Django如何实现内容缓存示例详解
2017/09/24 Python
Python 加密与解密小结
2018/12/06 Python
django的settings中设置中文支持的实现
2019/04/28 Python
python 设置输出图像的像素大小方法
2019/07/04 Python
详解python中index()、find()方法
2019/08/29 Python
Selenium启动Chrome时配置选项详解
2020/03/18 Python
Django配置跨域并开发测试接口
2020/11/04 Python
TUMI马来西亚官方网站:国际领先的高品质商旅箱包品牌
2018/04/26 全球购物
澳大利亚快时尚鞋类市场:Billini
2018/05/20 全球购物
一道SQL面试题
2012/12/31 面试题
大学毕业生通用自荐信范文
2013/10/31 职场文书
教师岗位职责范本
2013/12/29 职场文书
省优秀教师事迹材料
2014/01/30 职场文书
安全标语口号
2014/06/09 职场文书
珠宝的促销活动方案
2014/08/31 职场文书
护士长2014年终工作总结
2014/11/11 职场文书
2016年法制宣传月活动总结
2016/04/01 职场文书
left join、inner join、right join的区别
2021/04/05 MySQL