zoukankan      html  css  js  c++  java
  • 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
    

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

  • 相关阅读:
    PHP 使用 GET 传递数组变量
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
  • 原文地址:https://www.cnblogs.com/eline2018/p/10406587.html
Copyright © 2011-2022 走看看