博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
@***装饰器(python)
阅读量:4216 次
发布时间:2019-05-26

本文共 2750 字,大约阅读时间需要 9 分钟。

0 前言:

在阅读代码中,发现@***的什么的,原来这个就是大名鼎鼎的装饰器,然后就学习了下装饰器,记录下学习心得。

1 装饰器介绍:

python装饰器就是用于拓展原来函数功能的一种特殊的函数,特殊之处在于它返回的是一个函数。

优点:不用更改原代码前提下可以新增函数的功能。

应用场景:插入日志,性能测试,事务处理,提取大量函数中与本身功能无关的类似代码,达到代码重复使用的目的。

2 装饰器简单应用

用例子说明事物是最好懂的。

首先亮出原代码

import time def func():    print("hello")    time.sleep(1)    print("tian")

要求:记录函数的执行总时间

常规想法:更改原代码。

import timedef func():    startTime = time.time()    print("hello")    time.sleep(1)    print("tian")    endTime = time.time()    msecs = (endTime - startTime)*1000    print("time is %d ms" %msecs)

思考:如果使用装饰器呢?琢磨下面的代码就很好理解了。

import  timedef decorator(fun):    def wrapper():        startTime = time.time()        fun()        endTime = time.time()        msecs = (endTime - startTime)*1000        print("time is %d ms" %msecs)    return wrapper@decoratordef fun():    print("hello")    time.sleep(1)    print("tian")if __name__=="__main__":    f=fun    f()

3 装饰器高级应用 

3.1 带参数的装饰器

import timedef decorator(fun):    def wrapper(a,b):        startTime=time.time()        fun(a,b)        endTime=time.time()        msecs=(endTime - startTime)*1000        print("time is %d ms" %msecs)    return wrapper@decoratordef fun(a,b):    print("hello")    time.sleep(1)    print("result is %d" %(a+b))if __name__=="__main__":    f=fun    f(3,4)

3.2 带有不定参数的装饰器

以*开头,可以传多个参数,**是形参中按照关键字传值把多余的传值以字典的方式呈现。

*args:表示将实参中按照位置传值,多出来的值都给args,且以元祖的方式呈现。

**kwargs:表示形参中按照关键字传值把多余的传值以字典的形式呈现

import timedef decorator(fun):    def wrapper(*args,**kwargs):        startTime=time.time()        fun(*args,**kwargs)        endTime=time.time()        msecs=(endTime - startTime)*1000        print("time is %d ms" %msecs)    return wrapper@decoratordef fun1(a,b):    print("hello")    time.sleep(1)    print("result is %d" %(a+b))@decoratordef fun2(a,b,c):    print("hello")    time.sleep(1)    print("result is %d" %(a+b+c))if __name__=="__main__":    fun1(3,4)    fun2(3,4,5)

3.3 多个装饰器

#多个装饰器import timedef deco01(func):    def wrapper(*args, **kwargs):        print("this is deco01")        startTime = time.time()        func(*args, **kwargs)        endTime = time.time()        msecs = (endTime - startTime)*1000        print("time is %d ms" %msecs)        print("deco01 end here")    return wrapperdef deco02(func):    def wrapper(*args, **kwargs):        print("this is deco02")        func(*args, **kwargs)        print("deco02 end here")    return wrapper@deco01@deco02def func(a,b):    print("hello,here is a func for add :")    time.sleep(1)    print("result is %d" %(a+b))if __name__ == '__main__':    f = func    f(3,4)

输出结果:

this is deco01this is deco02hello,here is a func for add :result is 7deco02 end heretime is 1000 msdeco01 end hereProcess finished with exit code 0

观察输出顺序可以大概推断执行的顺序。多个装饰器执行的顺序就是从最后一个装饰器开始,执行到第一个装饰器,再执行函数本身。

4 参考

 

转载地址:http://zxtmi.baihongyu.com/

你可能感兴趣的文章
一种应用于GPS反欺骗的基于MLE的RAIM改进方法
查看>>
筑牢网络安全基座,安全护航经济数字化转型大会成功举办
查看>>
单元测试工具:单元测试的测试前置驱动条件
查看>>
汽车智不智能?“智能座舱”有话说
查看>>
自动驾驶汽车CAN总线数字孪生建模(一)
查看>>
自动驾驶汽车CAN总线数字孪生建模(二)
查看>>
自动驾驶汽车GPS系统数字孪生建模(一)
查看>>
自动驾驶汽车GPS系统数字孪生建模(二)
查看>>
上海控安入选首批工控安全防护能力贯标咨询机构名单
查看>>
自动驾驶汽车传感器数字孪生建模(一)
查看>>
CUDA 学习(四)、线程
查看>>
CUDA 学习(五)、线程块
查看>>
CUDA 学习(八)、线程块调度
查看>>
CUDA 学习(九)、CUDA 内存
查看>>
CUDA 学习(十一)、共享内存
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十四章 生化尖兵
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十五章 超级马里奥64
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十七章 游戏感的原理
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十八章 我想做的游戏
查看>>
游戏设计的艺术:一本透镜的书——第十章 某些元素是游戏机制
查看>>