Python装饰器举例分析
概述
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
我们要需要一个能测试函数运行时间的decorator,可以定义如下:
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("Run time is: %s" % (end_time - start_time))
return res
return wrapper
因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。我们要借助Python的@语法,把decorator置于函数的定义处:
@timer
def fun():
time.sleep(1)
print("This is a test")
return "OK"
运行结果就是:
This is a test
Run time is: 1.0000572204589844
OK
把@timer放在fun()处就相当于执行了语句:
fun = timer(fun)
如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,比如加上名字:
def timer(name):
def decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("Name is: %s ; Run time is: %s" % (name, (end_time - start_time)))
return res
return wrapper
return decorator
调用及结果显示如下:
@timer("Lance#")
def fun():
time.sleep(1)
print("This is a test")
return "OK"
This is a test
Name is: Lance# ; Run time is: 1.0000572204589844
OK
和两层嵌套的decorator相比,三层嵌套的效果是这样的:
fun = timer("Lance#")(fun)
因为函数也是对象,它也有__name__等属性。
在未加装饰器之前的fun()函数,调用 fun的__name__属性结果是 'fun',但经过decorator装饰之后的函数,它们的__name__已经从原来的'fun'变成了'wrapper'
所以,需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。
Python内置的functools.wraps就可以完成这个任务,所以,一个完整的decorator的写法如下:
import functools
def timer(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("Run time is: %s" % (end_time - start_time))
return res
return wrapper
整体代码如下:
__Author__ = "Lance#"
# -*- coding = utf-8 -*-
import time
import functools
def timer(name):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("Name is: %s ; Run time is: %s" % (name, (end_time - start_time)))
return res
return wrapper
return decorator
@timer("Lance#")
def fun():
time.sleep(1)
print("This is a test")
return "OK"
if __name__ == '__main__':
print(fun())
Python装饰器举例分析的更多相关文章
- [python 基础]python装饰器(一)添加functools获取原函数信息以及functools.partial分析
python装饰器学习的时候有两点需要注意一下 1,被装饰器装饰的函数取其func.__name__和func.func_doc的时候得到的不是被修饰函数的相关信息而是装饰器wrapper函数的doc ...
- Python装饰器由浅入深
装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...
- python 装饰器 一篇就能讲清楚
装饰器一直是我们学习python难以理解并且纠结的问题,想要弄明白装饰器,必须理解一下函数式编程概念,并且对python中函数调用语法中的特性有所了解,使用装饰器非常简单,但是写装饰器却很复杂.为了讲 ...
- Python装饰器探险
关于python装饰器的理解和用法,推荐廖雪峰老师和这一篇博客以及知乎 以下代码均已手动敲过,看完本篇内容,包你装饰器小成! 装饰器实际上就是为了给某程序增添功能,但该程序已经上线或已经被使用,那么就 ...
- Python装饰器的通俗理解
转载:http://blog.csdn.net/u013471155 在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略 ...
- python装饰器(docorator)详解
引言: 装饰器是python面向对象编程三大器之一,另外两个迭代器.生成器只是我现在还没有遇到必须使用的场景,等确实需要用到的时候,在补充资料:装饰器在某些场景真的是必要的,比如定义了一个类或者一个函 ...
- Python 装饰器学习心得
最近打算重新开始记录自己的学习过程,于是就捡起被自己废弃了一年多的博客.这篇学习笔记主要是记录近来看的有关Python装饰器的东西. 0. 什么是装饰器? 本质上来说,装饰器其实就是一个特殊功能的函数 ...
- (一)Python装饰器的通俗理解
在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略有领悟,我希望以下的内容会对你有帮助,我也努力通过通俗的方式使得对Py ...
- Python 装饰器初探
Python 装饰器初探 在谈及Python的时候,装饰器一直就是道绕不过去的坎.面试的时候,也经常会被问及装饰器的相关知识.总感觉自己的理解很浅显,不够深刻.是时候做出改变,对Python的装饰器做 ...
随机推荐
- C语言基础课第二次作业
一. 题目7-1 统计学生成绩 1.实验代码 #include<stdio.h> int main(void) { int i,grade,n; ,b=,c=,d=,e=; scanf( ...
- javascript字符串方法总结
一.单引号字符串内部可以使用双引号,双引号字符串内部也可以使用单引号 "hello 'world'" 'welcome "to" js' 二.多行和转义 如果要 ...
- ota升级动画背景色修改
https://wenku.baidu.com/view/0d63ad25192e45361066f549.html https://blog.csdn.net/huangyabin001/artic ...
- spring+shiro+ehcache整合
1.导入jar包(pom.xml文件) <!-- ehcache缓存框架 --> <dependency> <groupId>net.sf.ehcache</ ...
- C语言中的语句
• 表达式语句 表达式后加 ; 构成表达式语句. a = b+c; x+y i++ • 控制语句 完成一定的控制功能. if(...){...}else{...} ...
- EF6 学习笔记(五):数据库迁移及部署
EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 原文地址:Code First Migrations and Deployment 原文主要讲两部分:开发环境下 ...
- JavaScrip继承图文总结
JavaScript有多种继承模式,总结起来用到的方法有:原型链的传递.构造函数的借用.对象的复制. 这篇文章讲得很清晰,让我们明白:所有JS对象源于null,并通过原型指针和原型对象来实现继 ...
- 安装stress模拟linux系统资源消耗
1.安装yum源:yum install epel-release -y 2.安装stress:yum install stress -y 3.使用样例:stress -c 1 -t 60 4.测试场 ...
- 使用PostgreSQL进行中文全文检索
code[class*="language-"], pre[class*="language-"] { background-color: #fdfdfd; - ...
- MFS 服务扫描与爆破
MSF 服务发现 常用来发现局域网内,的常见服务,比如HTTP,FTP,TELNET等. MSF模块搜索: [root@localhost ~]# msfconsole msf5 > searc ...