python中的decorator的作用详解


Posted in Python onJuly 26, 2018

1、概念

装饰器(decorator)就是:定义了一个函数,想在运行时动态增加功能,又不想改动函数本身的代码。可以起到复用代码的功能,避免每个函数重复性编写代码,简言之就是拓展原来函数功能的一种函数。在python中,装饰器(decorator)分为 函数装饰器 和 类装饰器 两种。python中内置的@语言就是为了简化装饰器调用。

列出几个装饰器函数:

打印日志:@log

检测性能:@performance

数据库事务:@transaction

URL路由:@post('/register')

2、使用方法

(1)无参数decorator

编写一个@performance,它可以打印出函数调用的时间。

import time

def performance(f):
 def log_time(x):
  t1 = time.time()
  res = f(x)
  t2 = time.time()
  print 'call %s() in %fs' %(f.__name__,(t2 - t1))
  return res
 return log_time

@performance
def factorial(n):
 return reduce(lambda x,y : x*y,range(1,n+1))

print factorial(10)

运行结果:

call factorial() in 0.006009s 2 3628800

运行原理:

此时,factorial就作为performance的函数对象,传递给f。当调用factorial(10)的时候也就是调用log_time(10)函数,而在log_time函数内部,又调用了f,这就造成了装饰器的效果。说明f是被装饰函数,而x是被装饰函数的参数。

(2)带参数decorator

请给 @performace 增加一个参数,允许传入's'或'ms'。

import time

def performance(unit):
 def perf_decorator(f):
  def wrapper(*args, **kw):
   t1 = time.time()
   r = f(*args, **kw)
   t2 = time.time()
   t = (t2 - t1)*1000 if unit =='ms' else (t2 - t1)
   print 'call %s() in %f %s'%(f.__name__, t, unit)
   return r
  return wrapper
 return perf_decorator

@performance('ms') 
def factorial(n):
 return reduce(lambda x,y: x*y, range(1, n+1))

print factorial(10)

运行结果:

call factorial() in 9.381056 ms 2 3628800

运行原理:

它的内部逻辑为factorial=performance('ms')(factorial);

这里面performance('ms')返回是perf_decorator函数对象,performance('ms')(factorial)其实就是perf_decorator(factorial),然后其余的就和上面是一样的道理了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 列表(List)操作方法详解
Mar 11 Python
python根据文件大小打log日志
Oct 09 Python
python通过openpyxl生成Excel文件的方法
May 12 Python
Python实现Dijkstra算法
Oct 17 Python
pyqt远程批量执行Linux命令程序的方法
Feb 14 Python
python3.6 tkinter实现屏保小程序
Jul 30 Python
Python下opencv图像阈值处理的使用笔记
Aug 04 Python
Python爬虫实现的根据分类爬取豆瓣电影信息功能示例
Sep 15 Python
python pyinstaller打包exe报错的解决方法
Nov 02 Python
python模块hashlib(加密服务)知识点讲解
Nov 25 Python
python使用PIL剪切和拼接图片
Mar 23 Python
Pytest中skip skipif跳过用例详解
Jun 30 Python
python opencv实现旋转矩形框裁减功能
Jul 25 #Python
Python3匿名函数用法示例
Jul 25 #Python
Python实现动态添加属性和方法操作示例
Jul 25 #Python
利用pandas读取中文数据集的方法
Jul 25 #Python
利用pandas进行大文件计数处理的方法
Jul 25 #Python
使用python验证代理ip是否可用的实现方法
Jul 25 #Python
Python+Pandas 获取数据库并加入DataFrame的实例
Jul 25 #Python
You might like
PHP实现批量修改文件后缀名的方法
2015/07/30 PHP
CodeIgniter生成静态页的方法
2016/05/17 PHP
thinkphp Apache配置重启Apache1 restart 出错解决办法
2017/02/15 PHP
浅析PHP中的 inet_pton 网络函数
2019/12/16 PHP
JS 字符串连接[性能比较]
2009/05/10 Javascript
javascript Firefox与IE 替换节点的方法
2010/02/24 Javascript
juqery 学习之四 筛选过滤
2010/11/30 Javascript
jquery里的正则表达式说明
2011/08/03 Javascript
滚动条响应鼠标滑轮事件实现上下滚动的js代码
2014/06/30 Javascript
深入分析JQuery和JavaScript的异同
2014/10/23 Javascript
浅谈javascript中for in 和 for each in的区别
2015/04/23 Javascript
jQuery右下角旋转环状菜单特效代码
2015/08/10 Javascript
jQuery旋转木马式幻灯片轮播特效
2015/12/04 Javascript
jQuery实现的鼠标滑过弹出放大图片特效
2016/01/08 Javascript
基于Node.js实现nodemailer邮件发送
2016/01/26 Javascript
JavaScript面试题大全(推荐)
2016/09/22 Javascript
HTML中setCapture、releaseCapture 使用方法浅析
2016/09/25 Javascript
js鼠标按键事件和键盘按键事件用法实例汇总
2016/10/03 Javascript
详解angularjs 关于ui-router分层使用
2017/06/12 Javascript
详解Vue用cmd创建项目
2019/02/12 Javascript
Vue安装浏览器开发工具的步骤详解
2019/05/12 Javascript
[26:24]完美副总裁、DOTA2负责人蔡玮专访:电竞如人生
2014/09/11 DOTA
Python中MYSQLdb出现乱码的解决方法
2014/10/11 Python
Python实现统计代码行的方法分析
2017/07/12 Python
python生成tensorflow输入输出的图像格式的方法
2018/02/12 Python
Python 实现子类获取父类的类成员方法
2019/01/11 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
2020/04/14 Python
Pytest如何使用skip跳过执行测试
2020/08/13 Python
美国50岁以上单身人士约会平台:SilverSingles
2018/06/29 全球购物
如何使用PHP session
2015/04/21 面试题
幼儿园教师备课制度
2014/01/12 职场文书
幼儿园中秋节活动反思
2014/02/16 职场文书
小学生交通安全寄语
2015/02/27 职场文书
篮球赛新闻稿
2015/07/17 职场文书
java实现web实时消息推送的七种方案
2022/07/23 Java/Android
html网页引入svg图片的4种方式
2022/08/05 HTML / CSS