zoukankan      html  css  js  c++  java
  • 装饰器

     需求1:需要大长脸写一个功能,测试一下同事二狗的函数的执行效率
    import time #引入time模块
    print(time.time())

    def func1():
        time.sleep(1)
        print('来了,老弟')
    
    def func2():
        time.sleep(1)
        print('回手 掏 ,走位走位....')
    #
    #
    import time
    start_time = time.time()
    func1()
    end_time = time.time()
    print('此函数的执行时间是%s' % (end_time-start_time))
    
    import time
    start_time = time.time()
    func2()
    end_time = time.time()
    print('此函数的执行时间是%s' % (end_time-start_time))
    
    # 第一版本不好,重复造轮子,测试函数的效率 必须得复制代码测试 改版:

    # 第二版 将脸哥的代码封装到函数中,基本完成,
    import time
    
    def func1():
        time.sleep(0.6)
        print('来了,老弟')
    
    def func2():
        time.sleep(0.5)
        print('回手 掏 ,走位走位....')
    
    def timmer(f):
        start_time = time.time()
        f()
        end_time = time.time()
        print('此函数的执行时间是%s' % (end_time-start_time))
    timmer(func1)
    timmer(func2)

    # 第三版  领导要求在生产环境测试函数的真正的执行效率:线上500个函数
    # 线上问题:
        # 线上的函数你不改变
        # 函数的原本的调用方式不能改变
    import time
    def func1():
        time.sleep(0.6)
        print('来了,老弟')
    
    def func2():
        time.sleep(0.5)
        print('回手 掏 ,走位走位....')
    
    # 原本线上的调用方式:
    # func1()
    # func2()
    
    # 但是用了脸哥的测试效率的函数之后
    def timmer(f):
        start_time = time.time()
        f()
        end_time = time.time()
        print('此函数的执行时间是%s' % (end_time-start_time))
    
    # 此时你已经改变了原函数的调用方式,并且程序执行了两遍
    func1()
    timmer(func1)

    # 第四版:第三版 没有改变函数里面的函数体,但是改变了函数的调用方法,所以要解决:用最少的代码,解决调用方式一致性的问题。
    # 最终完成的需求 func1() 这个指令既要执行func1函数,又要测试效率
    import time
    def func1():
        time.sleep(0.6)
        print('来了,老弟')
    #
    # def func2():
    #     time.sleep(0.5)
    #     print('回手 掏 ,走位走位....')
    
    def timmer(f): # f = func1 函数的内存地址
        def inner():
            start_time = time.time()
            f()
            end_time = time.time()
            print('此函数的执行时间是%s' % (end_time-start_time))
        return inner
    func1 = timmer(func1) # = inner
    func1()  # inner()

    # 第五版: 最终基础版 python提供一个机制,优化,语法糖 @  上面还是不够优化,我们引入第5种python语法糖@   示例:func1 = timmer(func1) 就等于@timmer
    import time
    def timmer(f):  # f = func1 函数的内存地址
        def inner():
            start_time = time.time()
            f()
            end_time = time.time()
            print('此函数的执行时间是%s' % (end_time - start_time))
    
        return inner
    
    @timmer # func1 = timmer(func1)
    def func1():
        time.sleep(0.6)
        print('来了,老弟')
    
    func1()  # inner()
    @timmer
    def func2():
        time.sleep(0.6)
        print('来le')
    func2()
    
    @timmer
    def func3():
        time.sleep(0.6)
        print('')
    func3()

    二、被装饰函数带参数

    import time
    def timmer(f):  # f = func1或者func2 函数的内存地址
        def inner(*args, **kwargs):
            start_time = time.time()
            f(*args, **kwargs)
            end_time = time.time()
            print('此函数的执行时间是%s' % (end_time - start_time))
    
        return inner
    
    @timmer # func1 = timmer(func1) 在某个函数的上面加上这个
    def func1(a):
        time.sleep(0.6)
        print('来了,%s' % (a))
    func1('alex')
    
    @timmer  # func2 = timmer(func2)
    def func2(c,d):
        time.sleep(0.6)
        print('%s 年龄 %s' % (c,d))
    func2('二狗',21)

    三、被装饰函数带返回值

    import time
    def timmer(f):  # f = func1 函数的内存地址
        def inner(*args, **kwargs):
            start_time = time.time()
            ret = f(*args, **kwargs)
            end_time = time.time()
            print('此函数的执行时间是%s' % (end_time - start_time))
            return ret
    
        return inner
    @timmer  # func1 = timmer(func1)
    def func1(a):
        time.sleep(0.6)
        print('来了,%s' % (a))
        return 666
    print(func1('alex'))  # print(inner('alex'))

    总结:

    1、装饰器本质其实闭包,
    2、装饰器在不改变原函数的内部函数体以及调用方式的前提下,给函数增加了额外的功能:登录,注册,打印日志,函数效率等等。

    四、手写装饰器

    # 手写装饰器1,先写闭包:
    def wrapper(f):
        def inner():
            f()
        return inner
    
    # 手写装饰器2,增加参数:
    def wrapper(f):
        def inner(*args,**kwargs):
            f(*args,**kwargs)
        return inner
    # 手写装饰器3,增加返回值ret,增加函数部分:

    def wrapper(f): def inner(*args, **kwargs): ''' 执行被装饰的函数之前的操作''' print('执行之前', 555) #示例 ret = f(*args, **kwargs) print('执行之后', 666) #示例 ''' 执行被装饰的函数之后的操作''' return ret return inner @wrapper def func1(): pass func1()

  • 相关阅读:
    ElasticSearch搜索
    Muddery框架
    https和http的区别
    multiprocessing模块创建进程
    进程理论基础
    单例模式
    原型模式
    建造者模式
    StrutsTypeConverter的使用
    UML用例图之泛化(generalization)、扩展(extend)和包含(include)关系--UML一波流系列讲解
  • 原文地址:https://www.cnblogs.com/wangkaiok/p/9906830.html
Copyright © 2011-2022 走看看