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

    1. 装饰器

    (1)最简单的装饰器

    import time
    
    def timmer(f):
        start = time.time()
        f()
        end = time.time()
        print(end-start)
    
    def func():
        time.sleep(1)
        print('老板好')
    timmer(func)

    (2)有返回值的装饰器

    import time
    def timmer(f):  #装饰器函数
        def inner():
            start = time.time()
            ret = f() #被装饰的函数
            end = time.time()
            print(end-start)
            return ret
        return inner
    
    @timmer     #语法糖:放在被装饰函数的前一行
    def func():
        time.sleep(1)
        print('你好我好大家好')
        return '新年好'
    
    # func = timmer(func)   有语法糖,可以不写此句话,同义
    
    ret = func()    #inner()
    print(ret) 

    (3)带一个参数的装饰器

    import time
    def timmer(f):  #装饰器函数
        def inner(a):
            start = time.time()
            ret = f(a) #被装饰的函数
            end = time.time()
            print(end-start)
            return ret
        return inner
    
    @timmer     #语法糖:放在被装饰的函数前一行
    def func(a):
        time.sleep(1)
        print('你好我好大家好',a)
        return '新年好'
    # func = timmer(func)   有语法糖,可以不写此句话,同义
    
    ret = func(1)    #inner()
    print(ret)

    (4)带多个参数的装饰器

    import time
    def timmer(f):  #装饰器函数
        def inner(*args,**kwargs):
            start = time.time()
            ret = f(*args,**kwargs) #被装饰的函数
            end = time.time()
            print(end-start)
            return ret
        return inner
    
    @timmer     #语法糖:放在被装饰的函数前一行
    def func(a,c,d,b):
        time.sleep(1)
        print('你好我好大家好',a,c,d,b)
        return '新年好'
    
    # func = timmer(func)   有语法糖,可以不写此句话,同义
    
    # ret = func(1,2)    #inner()
    # ret = func(1,b = 2)    #inner()
    ret = func(1,3,4,b = 2)    #inner()
    print(ret)

    2. 装饰器的作用:

      不修改函数的调用方式,但是还想在原来的函数前后添加功能
      timmer就是一个装饰器函数,只是对一个函数有些装饰的作用

    3. 开放封闭原则   

      开放:对扩展是开放的
      封闭:对修改时封闭的

    4. 装饰器的固定模式

    import time 
    
    def wrapper(func):  # 装饰器函数,func = qqxing
        def inner(*args, **kwargs):
         #被装饰函数之前要做的
            ret = func(*args, **kwargs)  # func是被装饰的函数
         #被装饰函数之前要做的
            return ret
        return inner
    
    @wrapper      # qqxing = wrapper(qqxing)
    def qqxing():
        print(123)
    ret = qqxing()  # inner
    print(ret)

     5. 装饰器的进阶

    (1)functools.wrap

    from functools import wraps
    def wrapper(func):#(1)
        @wraps(func)
        def inner(*args,**kwargs):#(4)
            print('在被装饰的函数执行之前做的事')
            ret = func(*args,**kwargs)#(8) holiday(*(3),**{}) #(12)ret接收返回值
            print('在被装饰的函数执行之后做的事')
            return ret#(14)
        return inner#(5)
    
    @wrapper    #(6)赋值#holiday = wrapper(holiday)   #(2,3)
    def holiday(day):
        '''这是一个放假通知'''
        print('中秋放假%s天'%day)#(10)
        return '好开心'#(11)
    print(holiday.__name__) #inner(没有wraps)
    print(holiday.__name__) #holiday(有wraps之后)
    print(holiday.__doc__)
    
    ret = holiday(3)    #(7)inner(3)    #(15)ret接收返回值
    print(ret)#(16)

     运行结果:

    (2)带参数的装饰器

    import time
    FLAGE = True
    def timmer_out(flag):
        def timmer(func):
            def inner(*args, **kwargs):
                if flag:
                    start = time.time()
                    ret = func(*args, **kwargs)
                    end = time.time()
                    print(end - start)
                else:
                    ret = func(*args, **kwargs)
                    return ret
            return inner
        return timmer
    
    @timmer_out(FLAGE)  #timmer = timmer_out(FLAGE)     @timmer
    def wahaha():
        time.sleep(0.2)
        print('wahahahahahaha')
    
    @timmer_out(FLAGE)
    def erguotou():
        time.sleep(0.1)
        print('erguotoutoutou')
    
    wahaha()
    erguotou()

    运行结果:

    (3)多个装饰器装饰同一个函数

       <1>两层

    def wrapper1(func):
        def inner1():#func-->f
            print('wrapper1,before func')
            func()  #f
            print('wrapper1,after func')
        return inner1
    def wrapper2(func):#func-->inner1
        def inner2():
            print('wrapper2,before func')
            func()  #inner1
            print('wrapper2,after func')
        return inner2
    @wrapper2   #f = wrapper2(f) = wrapper2(inner1) == inner2
    @wrapper1   #f = wrapper1(f) = inner1
    
    def f():
        print('in f')
    f() #-->inner2()

      运行结果:

      <2>三层

    def wrapper1(func):
        def inner1():
            print('wrapper1,before func')
            func()
            print('wrapper1,after func')
        return inner1
    def wrapper2(func):
        def inner2():
            print('wrapper2,before func')
            func()
            print('wrapper2,after func')
        return inner2
    def wrapper3(func):
        def inner3():
            print('wrapper3,before func')
            func()
            print('wrapper3,after func')
        return inner3
    @wrapper3
    @wrapper2
    @wrapper1
    def f():
        print('in f')
    f()

      运行结果:

      <3>有返回值的完整的三层

    def wrapper1(func):
        def inner1():
            print('wrapper1,before func')
            ret = func()
            print('wrapper1,after func')
            return ret
        return inner1
    def wrapper2(func):
        def inner2():
            print('wrapper2,before func')
            ret = func()
            print('wrapper2,after func')
            return ret
        return inner2
    def wrapper3(func):
        def inner3():
            print('wrapper3,before func')
            ret = func()
            print('wrapper3,after func')
            return ret
        return inner3
    @wrapper3
    @wrapper2
    @wrapper1
    def f():
        print('in f')
        print('哈哈哈')
    f()

      运行结果:

     

      <4>执行顺序:

    长得丑就应该多读书。我爱学习,只爱学习,最爱学习!
  • 相关阅读:
    千个常用DOS命令全面收藏
    面向对象设计的11原则
    SQL语句判断指定的数据库、表、字段、存储过程是否存在
    ASP.NET MVC2 Areas区域新概念
    标准的 SQL 解析顺序
    Improvements to workspaces in TFS 2010
    jquery ajax return值不能取得的解决方案
    用 SQL 语句创建数据库用户(SQL Server 2005)
    简单实现.net MVC自定义错误处理页面
    自定义截图类(C#)
  • 原文地址:https://www.cnblogs.com/xc-718/p/9672843.html
Copyright © 2011-2022 走看看