Python之装饰器

1、什么是装饰器

  python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能

2、用一个简单例子说明装饰器的优点

 原始代码、核心代码

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

需求:计算执行上述代码的时间

解决方法:原始侵入,篡改原函数

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

需求:公司核心代码已经运行稳定,不能再其修改

解决方法:进入新的计算时间函数

import time   // 避免直接侵入原函数修改,但是生效需要再次执行函数
def deco(func):
    startTime = time.time()
    func()
    endTime = time.time()
    msecs = (endTime - startTime) * 1000
    print("time is %d ms" % msecs)

def func():
    print("hello")
    time.sleep(1)
    print("world !")

if __name__ == "__main__":
    f = func
    deco(func)
    print("f.__name__is",f.__name__)

需求:公司核心代码有很多个函数组成,如果想要拓展这些功能,就需要执行多次deco函数

解决方法:使用我们今天介绍的修饰器,既不需要侵入,也不需要函数重复执行

import time    // 既不需要侵入,也不需要重复执行函数
def deco(func):
    def wrapper():
        startTime = time.time()
        func()
        endTime = time.time()
        msecs = (endTime - startTime) * 1000
        print("time is %d ms" % msecs)
    return wrapper

@deco
def func():
    print("hello")
    time.sleep(1)
    print("world !")

if __name__ == "__main__":
    f = func    # 这里f被赋值为func,执行f()就是执行func()
    f()

  这里的deco函数就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。其中作为参数的这个函数func()就在返回函数wrapper()的内部执行。然后在函数func()前面加上@deco,func()函数就相当于被注入了计时功能,现在只要调用func(),它就已经变身为“新的功能更多”的函数了。

需求: 核心函数有的有一个参数,有的有多个参数

import time  // 带有固定个数参数的装饰器
def deco(func):
    def wrapper(a,b):
        startTime = time.time()
        func(a,b)
        endTime = time.time()
        msecs = (endTime - startTime) * 1000
        print("time is %d ms" % msecs)
    return wrapper

@deco
def 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被赋值为func,执行f()就是执行func()
    f(3,4)

import time    // 带有不定参数的装饰器
def deco(func):
    def wrapper(*args,**kwargs):
        startTime = time.time()
        func(*args,**kwargs)
        endTime = time.time()
        msecs = (endTime - startTime) * 1000
        print("time is %d ms" % msecs)
    return wrapper

@deco
def func(a,b):
    print("hello,here is a func for add:")
    time.sleep(1)
    print("result is %d" % (a+b))

@deco
def func2(a,b,c):
    print("hello,here is a func for add:")
    time.sleep(1)
    print("result is %d" % (a+b+c))

if __name__ == "__main__":
    f = func    # 这里f被赋值为func,执行f()就是执行func()
f(3,4)
func2(3,4,5)

需求:一个函数需要拓展多个功能,需要使用多个装饰器

import time  // 多个装饰器
def deco01(func):
    print("22222222")
    def wrapper(*args,**kwargs):
        print("33333333")
        startTime = time.time()
        func(*args,**kwargs)
        endTime = time.time()
        msecs = (endTime - startTime) * 1000
        print("time is %d ms" % msecs)
        print("deco01 end here")
    return wrapper

def deco02(func):
    print("11111111")
    def wrapper(*args,**kwargs):
        print("44444444")
        func(*args,**kwargs)
        print("deco02 end here")
    return wrapper

@deco01
@deco02
def 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被赋值为func,执行f()就是执行func()
    f(3,4)
// 运行结果
11111111
22222222
33333333
44444444
hello, here is a func for add:
result is 7
deco02 end here
time is 1001 ms
deco01 end here

  注意:多个装饰器执行的顺序就是从最后一个装饰器开始,执行到第一个装饰器,再执行函数本身

posted @ 2019-02-20 14:51  彩虹灵魂  阅读(170)  评论(0编辑  收藏  举报