• 装饰器


    什么是装饰器

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

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

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

    装饰器本质就是一个函数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)
            
    
  • 相关阅读:
    java数组
    python中的换行与不换行
    金融业务知识2---资金的时间价值与跨时期优化
    金融业务知识1---金融和金融系统
    你真的理解正向代理和反向代理吗?
    webpack(9)plugin插件功能的使用
    webpack(8)vue组件化开发的演变过程
    webpack(7)webpack使用vue配置
    webpack(6)webpack处理图片
    webpack(5)webpack处理css文件
  • 原文地址:https://www.cnblogs.com/aden668/p/11340517.html
Copyright © 2020-2023  润新知