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

    导读目录:

    1、装饰器的形成过程

      1.1  带返回值的装饰器(被装饰函数不带参)

      1.2 带参数的装饰器(进阶)

      1.3 装饰带参函数的装饰器

      1.4 多个装饰器装饰一个函数(进阶)

      1.5 查看函数信息的一些方法

      1.6 装饰器的固定模式demo

    2、开放封闭原则

    1、装饰器

     装饰器的作用:不想修改函数(func)的调用方式,但是还想在原来的函数前后添加功能。

      1.1  带返回值的装饰器(被装饰函数不带参)

    import time
    #### 功能体,通过函数闭包
    def timer(f):   # 装饰器函数
        def inner():
            start = time.time()
            ret = f()     #被装饰的函数,ret = '新年好'
            end = time.time()
            print(end - start)
            return ret
        return inner     # 千万别加(),这里返回函数名【地址】,因为inner()没有返回值(None)
    
    @timer         #语法糖:@装饰器函数名
    def func():    # 被装饰的函数  <=> func = timer(func) = inner
        time.sleep(0.1)
        print('程序运行时间如下:')
        return '新年好'
    
    ret = func()      # <=> ret = inner(),return '新年好'
    print(ret)
    
    运行结果:
    程序运行时间如下:
    0.10062098503112793
    新年好

      1.2 带参数的装饰器(进阶)

    import time
    # FLAG = False
    FLAG = True       #True的时候,执行装饰器函数
    def timmer_out(flag):        #三层装饰器函数
        def timmer(func):
            def inner(*args,**kwargs):
                if flag:    #flag = True:计算函数执行的时间
                    start = time.time()
                    ret = func(*args,**kwargs)
                    end = time.time()
                    print(end - start)
                    return ret
                else:    #flag = False:返回被装饰的函数
                    ret = func(*args, **kwargs)
            return inner
        return timmer
    
    @timmer_out(FLAG)  # 先调用timerout(FLAG)函数,return timmer;再作为timmer装饰器
    def wahaha():      # timerout(FLAG)=timmer,@timmer ==> wahaha = timmer(wahaha) = inner
        time.sleep(0.1)
        print('wahaha函数运行时间:')
    
    # timmer = timmer_out(FLAG)
    @timmer_out(FLAG)
    def erguotou():
        time.sleep(0.1)
        print('erguotou函数运行时间:')
    
    wahaha()
    erguotou()
    
    # 运行结果:
    wahaha函数运行时间:
    0.10001826286315918
    erguotou函数运行时间:
    0.1002960205078125

      1.3 装饰带参函数的装饰器

    import time
    
    def timer(f):
        def inner(*args,**kwargs):
            start = time.time()
            ret = f(*args,**kwargs)    #func(2,b='5')  ret='新年好'
            end = time.time()
            print(end - start)
            return ret
        return inner
    
    @timer       #  func = timer(func) = inner
    def func(a,b):    # 被装饰的函数
        time.sleep(0.1)
        print('程序运行时间如下:',a,b)
        return '新年好'
    
    ret = func(2,b='5')   # 执行inner(2,b='5')
    print(ret)
    
    #运行结果:
    程序运行时间如下: 2 5
    0.10095524787902832
    新年好

      1.4 多个装饰器装饰一个函数(进阶)

    def wrapper1(func):
        def inner1():
            print('wrapper1,before func')
            ret = func()   #f   ret = '哈哈哈'
            print('wrapper1,after func')
            return ret  
        return inner1
    
    def wrapper2(func):
        def inner2():
            print('wrapper2,before func')
            ret = func()      #inner1()
            print('wrapper2,after func')
            return ret
        return inner2
    
    def wrapper3(func):
        def inner3():
            print('wrapper3,before func')
            ret = func()      #inner2()
            print('wrapper3,after func')
            return ret
        return inner3
    
    @wrapper3     #f = wrapper3(f) = wrapper3(inner2) = inner3
    @wrapper2     #f = wrapper2(f) = wrapper2(inner1) = inner2
    @wrapper1     #f = wrapper1(f) = inner1  【函数f()先找最近的装饰器wrapper1】
    def f():
        print('in f')
        return '哈哈哈'
    print(f())
    
    运行结果:
    wrapper3,before func
    wrapper2,before func
    wrapper1,before func
    in f
    wrapper1,after func
    wrapper2,after func
    wrapper3,after func
    哈哈哈

      1.5 查看函数信息的一些方法

    def index():
        '''这是一个主页信息'''
        print('from index')
    
    print(index.__doc__)      # 查看函数注释的方法
    print(index.__name__)   # 查看函数名的方法

      1.6 装饰器的固定模式demo

    import time
    
    def wrapper(f):   # 装饰器函数
        def inner(*args, **kwargs):
            '''在被装饰的函数之前要做的事儿'''
            ret = f(*args,**kwargs)     #执行func()
            '''在被装饰的函数之后要做的事儿'''
            return ret
        return inner    # 千万别加(),这里返回函数名【地址】,因为inner()没有返回值(None)
    
    @wrapper       # 语法糖:@装饰器函数名
    def func():    # 被装饰的函数
        time.sleep(0.1)
        print('程序运行时间如下:')
        return '新年好'
    
    ret = func()
    print(ret)

    2、开放封闭原则

    # 1.对扩展是开放的
    
      为什么要对扩展开放呢?
    
      任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
    
    # 2.对修改是封闭的
    
      为什么要对修改封闭呢?
    
      因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
    
        装饰器完美的遵循了这个开放封闭原则。
  • 相关阅读:
    【USACO】接住苹果
    【题解】任务分配
    【伪·题解】高级打字机
    【noi openjudge题解】最低通行费
    【USACO】草地排水
    【POJ2186】受牛仰慕的牛
    【NOIP2011提高组】选择客栈
    [bzoj1026][SCOI2009]windy数 (数位dp)
    [bzoj1025][SCOI2009]游戏 (分组背包)
    [bzoj1024][SCOI2009]生日快乐 (枚举)
  • 原文地址:https://www.cnblogs.com/timetellu/p/10682702.html
Copyright © 2011-2022 走看看