简单上手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接收多播数据的代码
Mar 01 Python
python在linux系统下获取系统内存使用情况的方法
May 11 Python
在Python中操作列表之List.pop()方法的使用
May 21 Python
Python编程中对文件和存储器的读写示例
Jan 25 Python
总结网络IO模型与select模型的Python实例讲解
Jun 27 Python
用python实现k近邻算法的示例代码
Sep 06 Python
使用Flask-Cache缓存实现给Flask提速的方法详解
Jun 11 Python
Django CBV类的用法详解
Jul 26 Python
Python中zip()函数的简单用法举例
Sep 02 Python
python3 dict ndarray 存成json,并保留原数据精度的实例
Dec 06 Python
python中关于数据类型的学习笔记
Jul 19 Python
Python实现文本文件拆分写入到多个文本文件的方法
Apr 18 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 生成签名及验证签名详解
2016/10/26 PHP
DWZ+ThinkPHP开发时遇到的问题分析
2016/12/12 PHP
PHP PDOStatement::fetchAll讲解
2019/01/31 PHP
javascript 禁止复制网页
2009/06/11 Javascript
javaScript call 函数的用法说明
2010/04/09 Javascript
js获得鼠标的坐标值的方法
2013/03/13 Javascript
onkeydown事件解决按回车键直接提交数据的需求
2013/04/11 Javascript
微信中一些常用的js方法汇总
2015/03/12 Javascript
javascript实现对表格元素进行排序操作
2015/11/18 Javascript
jQuery实现表格行和列的动态添加与删除方法【测试可用】
2016/08/01 Javascript
探讨跨域请求资源的几种方式(总结)
2016/12/02 Javascript
详解Javascript数据类型的转换规则
2016/12/12 Javascript
原生JS实现图片轮播切换效果
2016/12/15 Javascript
jQuery插件HighCharts实现的2D面积图效果示例【附demo源码下载】
2017/03/15 Javascript
js实现图片粘贴上传到服务器并展示的实例
2017/11/08 Javascript
基于js中style.width与offsetWidth的区别(详解)
2017/11/12 Javascript
利用babel将es6语法转es5的简单示例
2017/12/01 Javascript
原生javascript运动函数的封装示例【匀速、抛物线、多属性的运动等】
2020/02/23 Javascript
[44:22]完美世界DOTA2联赛循环赛 FTD vs PXG BO2第一场 11.01
2020/11/02 DOTA
编写Python脚本使得web页面上的代码高亮显示
2015/04/24 Python
Python中的map()函数和reduce()函数的用法
2015/04/27 Python
python 发送邮件的示例代码(Python2/3都可以直接使用)
2020/12/03 Python
使用CSS3来制作消息提醒框
2015/07/12 HTML / CSS
详解HTML5中download属性的应用
2015/08/06 HTML / CSS
HTML最新标准HTML5总结(必看)
2016/06/13 HTML / CSS
美国最好的钓鱼、狩猎和划船装备商店:Bass Pro Shops
2018/12/02 全球购物
阿联酋最好的手机、电子产品和家用电器网上商店:Eros Digital Home
2020/08/09 全球购物
车间操作工岗位职责
2013/12/19 职场文书
岗位标兵事迹材料
2014/05/17 职场文书
2014年党员承诺书范文
2014/05/20 职场文书
2015年档案管理员工作总结
2015/05/13 职场文书
二年级作文之动物作文
2019/11/13 职场文书
python批量创建变量并赋值操作
2021/06/03 Python
node快速搭建后台的实现步骤
2022/02/18 NodeJs
Python使用PyYAML库读写yaml文件的方法
2022/04/06 Python
Linux、ubuntu系统下查看显卡型号、显卡信息详解
2022/04/07 Servers