zoukankan      html  css  js  c++  java
  • Python初学者第二十三天 函数进阶(2)装饰器

     装饰器:

    需求----> 写一个功能,测试其他同事函数的调用效率。  

    第一版:功能版

    import time
    
    def func():
        time.sleep(0.2)
        print('非常复杂')
    
    def func1():
        time.sleep(0.3)
        print('超级复杂')
    
    # print(time.time())
    start_time = time.time()
    func()
    end_time = time.time()
    print('此函数的执行效率为%s' % (end_time - start_time))
    View Code

    第二版:函数版

    import time
    def func():
        time.sleep(0.2)
        print('非常复杂')
    func()
    def func1():
        time.sleep(0.3)
        print('超级复杂')
    def timmer(f):
        start_time = time.time()
        f()
        end_time = time.time()
        print('此函数的执行效率为%s' % (end_time - start_time))
    timmer(func)
    # timmer(func1)
    # func()
    func()
    # 如果在实际项目中测试函数,
    # 假如函数有1500个,那么你1500个timmer(func),工作量很大。
    # 你要在不改变函数执行的指令下,同时测试效率。
    View Code

    第三版:在不改变被测函数的执行方式下,同时测试执行效率

    import time
    
    def func():
        time.sleep(0.2)
        print('非常复杂')
    # func()
    def func1():
        time.sleep(0.3)
        print('超级复杂')
    
    def timmer(f):
        start_time = time.time()
        f()
        end_time = time.time()
        print('此函数的执行效率为%s' % (end_time - start_time))
    
    timmer(func)
    timmer(func1)
    func()
    f1 = func
    func = timmer
    func(f1)  # timer(func)
    View Code

    装饰器的雏形:

    import time
    def func():
        time.sleep(0.2)
        print('非常复杂')
    # func()
    
    def func1():
        time.sleep(0.3)
        print('超级复杂')
    def timmer(f):
        def inner():
            start_time = time.time()
            f()
            end_time = time.time()
            print('此函数的执行效率为%s' % (end_time - start_time))
        return inner
    # 语法糖 @
    func = timmer(func)
    func()
    func1 = timmer(func1)
    func1()
    View Code

    装饰器的优化: # timmer 就是装饰器: 在不改变原函数的调用指令情况下,给原函数增加额外的功能。

    在被测函数上方@timmer 即添加装饰器。代码从上执行时,遇到@timmer 会往下走一层,相当于func = timmer(func)

    import time
    
    def timmer(f):
        def inner():
            start_time = time.time()
            f()
            end_time = time.time()
            print('此函数的执行效率为%s' % (end_time - start_time))
        return inner
    
    @timmer # func = timmer(func)
    def func():
        time.sleep(0.2)
        print('非常复杂')
    func()
    @timmer # func1 = timmer(func1)
    def func1():
        time.sleep(0.3)
        print('超级复杂')

    装饰器基础进阶1:带参数的装饰器  #*args,**kwargs 万能传参

    import time
    
    def timmer(f):
        def inner(*args,**kwargs):  # 函数的定义: * 聚合。args = (1,2,3,434545,4234.)
            # a1 = 'wusir'
            # b1 = 'alex'
            start_time = time.time()
            f(*args,**kwargs)  # 函数执行:* 打散。f(*(1,2,3,434545,4234.),)
            end_time = time.time()
            print('此函数的执行效率为%s' % (end_time - start_time))
        return inner
    
    @timmer # func = timmer(func)
    def func(a,b):
        time.sleep(0.2)
        print('非常复杂%s%s'% (a,b))
    func('wusir','alex')  # inner()

    装饰器基础进阶2:有返回值的装饰器  

    import time
    
    def timmer(f):  # f = func
        def inner(*args,**kwargs):
            start_time = time.time()
            ret = f(*args,**kwargs)  # func()
            end_time = time.time()
            print('此函数的执行效率为%s' % (end_time - start_time))
            return ret
        return inner
    
    @timmer # func = timmer(func)
    def func(a,b):
        time.sleep(0.2)
        print('非常复杂%s%s'% (a,b))
        return 666
    ret = func('wusir','alex')  # inner()
    print(ret)
    
    @timmer # func = timmer(func)
    def func(a,b,c):
        time.sleep(0.2)
        print('非常复杂%s%s%s'% (a,b,c))
    func('wusir','alex','barry')  # inner()
    装饰器用途:登录认证,打印日志等等。
    总结:
    其实装饰器本质是闭包,他的传参,返回值都是借助内层函数inner,
    他之所以借助内层函数inner 就是为了让被装饰函数 在装饰器装饰前后,没有任何区别。
    看起来没有变化。

    装饰器的标准格式:
    def auth(f): # f = func3函数名
        def inner(*args,**kwargs):  #万能传参
            ret = f(*args,**kwargs)
            return ret         #返回值
        return inner
    
    @auth
    def comment():
        print('欢迎来到评论页面')
    comment()
    
    
  • 相关阅读:
    BZOJ1527 : [POI2005]Pun-point
    2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    NAIPC-2016
    BZOJ2498 : Xavier is Learning to Count
    ACM ICPC Vietnam National Second Round
    XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
    XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
    HDU5509 : Pattern String
    BZOJ4583 : 购物
  • 原文地址:https://www.cnblogs.com/fany-mok/p/8387718.html
Copyright © 2011-2022 走看看