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

    什么是装饰器

    装饰器是指装饰的工具(函数),这个函数具有装饰作用.因此定义装饰器就是定义一个函数,只不过该函数的功能是用来为其他函数添加额外的功能.

    注意: 装饰器本身其实是可以任意可调用的对象

    ​ 被装饰的对象也可以是任意可调用的对象

    装饰器本质就是一个函数A,装饰的对象也是一个函数B,用一个函数A去装饰一个函数B

    装饰器的实现必须遵循两大原则:

    1. 不改变函数B的调用方式
    2. 不改变函数B的源代码

    装饰器的使用

    改变源代码

    import time
    
    
    def index():
        start = time.time()
        print('welcome to index')
        time.sleep(1)
        end = time.time()
        print(start-end)
    
    
    index()
    

    welcome to index
    -1.0000019073486328

    编写重复代码

    import time
    
    
    def index():
        print('welcome to index')
        time.sleep(1)
    
    
    def f2():
        print('welcome to index')
        time.sleep(1)
    
    
    start = time.time()
    index()
    end = time.time()
    print(start-end)
    
    start = time.time()
    f2()
    end = time.time()
    print(start-end)
    

    welcome to index
    -1.0004847049713135
    welcome to index
    -1.0000324249267578

    第一种传参方式:改变调用方法

    import time
    
    def index():
        print('welcome to index')
        time.sleep(1)
    
    def time_count(func):
        start = time.time()
        func()
        end = time.time()
        print(start-end)
    
    
    time_count(index)
    

    welcome to index
    -1.0003643035888672

    第二种传参方式:包给函数-外包

    import time
    
    def index():
        print('welcome to index')
        time.sleep(1)
    
    def time_count(func):
        # func = 最原始的index
        def wrapper():
            start = time.time()
            func()
            end = time.time()
            print(start-end)
        return wrapper
    
    # f = time_count(index)
    # f()
    
    
    index = time_count(index)  # index为被装饰函数的内存地址,即index = wrapper
    index()  # wrapper()
    

    welcome to index
    -1.0000269412994385

    装饰器语法糖

    在被装饰函数正上方,并且是单独一行写上@装饰器名

    import time
    def deco(func):
        def f1(*args, **kwargs):
            print('args:',args)  # (10,)
            print('kwargs:',kwargs)
            start = time.time()
            # *args = *(10,) 10
            res = func(*args, **kwargs)  # 真正的index()
            end = time.time()
            print(end - start)
            return res
        return f1
    
    @deco   # 语法糖(更精简的代码)   index = deco(index)
    def index(x, a=1):
        print('x', x)
        print('a', a)
        print('hello index')
        time.sleep(1)
    
        return 123
    
    #重新创建的index = deco(index真正的index)
    index = deco(index)  # index  = f1
    index(10)  # f1(1)
    
    

    args: (10,)
    kwargs: {}
    args: (10,)
    kwargs: {}
    x 10
    a 1
    hello index
    1.00038743019104
    1.00038743019104

    三层装饰器

    给双层装饰器加参数

    # 判断账号密码来自于哪个地方
    def auth(engine):
        def login(func):
            def inner(*args, **kwargs):
                # 登录功能
                if engine == 'file':
                    username = input('usrename:')
                    pwd = input('pwd:')
                    if username == 'nick' and pwd == '123':
                        print('登录成功')
                        res = func(*args, **kwargs)  # shopping()
                        return res
                    else:
                        print('登录失败')
    
                elif engine == 'db':
                    print('账号密码来自于数据库,非法请求')
    
            return inner
        return login
    
    @auth('db')
    def shopping():
        print('shopping')
    
    
    # login = auth('db')  # login = login
    # shopping = login(shopping)  # shopping = inner
    shopping() # inner()
    

    装饰器模板

    双层装饰器

    def outter(func):
        def inner(*args,**kwargs): #wrapp是未来要运行的函数
            #加功能
            res=func(*args,**kwargs) #func是被装饰的函数
            return res
        return inner
    
    @outter
    def shopping():
        print(shopping)
            
    

    三层装饰器

    def sancneg(engine):
        def outter(func):
            def inner(*args, **kwargs): #wrapper是未来要运行的函数
                # 加功能
                print(engine)
                res = func(*args, **kwargs) #func是被装饰的函数
                return res
    
            return inner
        
        return outter
    
    @sancneg('file')
    def shopping():
        print(shopping)
            
    
  • 相关阅读:
    广域网(ppp协议、HDLC协议)
    0120. Triangle (M)
    0589. N-ary Tree Preorder Traversal (E)
    0377. Combination Sum IV (M)
    1074. Number of Submatrices That Sum to Target (H)
    1209. Remove All Adjacent Duplicates in String II (M)
    0509. Fibonacci Number (E)
    0086. Partition List (M)
    0667. Beautiful Arrangement II (M)
    1302. Deepest Leaves Sum (M)
  • 原文地址:https://www.cnblogs.com/aden668/p/11340517.html
Copyright © 2011-2022 走看看