• 装饰器


    装饰器

    定义

    在不改变函数的源码和调用方式的情况下,给函数加功能

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

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

    分类

    双层装饰器

    例如,函数world是一个完整的功能函数,想要给world函数增加一个程序运行时长的功能,但不改变world函数的源码和调用方式,如何实现呢?

    这样,我们就可以用到装饰器了:

    import time
    
    def time_world(func): # func是真正的world
        """装饰函数"""
        def add():
            # 增加功能部分
            t1 = time.time()  # func() == world()
            func()
            t2 = time.time()
            print(t2 - t1)
        return add
    
    def world():
        """被装饰函数"""
        print('hello world!')
        time.sleep(1)
    world = time_world(time)
    world() # 调用方式不变world(),实际是调用add()
    
    """
    用语法糖来调用更简单
    @time_world
    def world():
        """被装饰函数"""
        print('hello world!')
        time.sleep(1)
    world()
    """
    

    三层装饰器

    三层装饰器就是给双层装饰器加参数

    例如,给shopping函数增加登录功能,并且传入登录方式变量,如果登录方式是file,则登录成功,如果是db,则登录非法。

    因为涉及到传值,双层装饰器显然实现较为困难,因此,引入三层装饰器:

    def three(gen):
        def login(func):
            def inner(*args,**kwargs): # 接收shopping传的所有值
                if gen == 'file':
                    name = input('name:')
                    pwd = input('password:')
                    # 假定name,pwd固定
                    if name == 'wzh' and pwd == '123':
                        print('success!')
                        res = func(*args,**kwargs)
                        return res
                    else:
                        print('default')
                 elif gen == 'db':
                    print('登录非法!')
    		return inner
        return login
    
    @three('file')
    def shopping():
        print('shopping!')
        
    shopping()         
    

    双层语法糖

    执行顺序相关

    # 双层语法糖
    def outer1(func):
        def inner(*args,**kwargs):  # 接收index里的参数
            """功能模块"""
            print('----------------')
            res = func(*args,**kwargs)
            print('----------------')
            return res   # 返回index里的参数
        return inner
    def outer2(func):
        def inner(*args,**kwargs):  # 接收index里的参数
            """功能模块"""
            print('****************')
            res = func(*args,**kwargs)
            print('****************')
            return res   # 返回index里的参数
        return inner
    
    @outer1
    @outer2
    def f():
        print('success')
    f()
    
    """
    ----------------
    ****************
    ssss
    ****************
    ----------------
    """
    

    装饰器模板(重要)

    # 双层装饰器
    def two(func):
        def two_inner(*args,**kwargs):
            """功能模块"""
            res = func(*args,**kwargs)
    		return res
        return inner
    @two
    def f():
        pass
    f()
    
    # 三层装饰器
    def three(value):
        def two(func):
            def innere(*args,**kwargs):
                """功能模块"""
                print(value)
                res = func(*args,**kwargs)
                return res
            return inner
        return two
    @three('shabi')
    def f():
        pass
    f()
    
  • 相关阅读:
    Qt 利用XML文档,写一个程序集合 二
    Qt 利用XML文档,写一个程序集合 一
    Qt QpushButton 实现长按下功能
    Qt 将字符串转成16进制显示
    Qt-QML-Canvas-雷达扫描仪表简单
    Qt-QML-电子罗盘
    Qt-QML-Canvas写个小小的闹钟
    Qt-Qt5最新增加程序图标方式
    Qt-QMl-自定义自己想要的TabView
    设置position:fixed后元素脱离标准流的解决方法
  • 原文地址:https://www.cnblogs.com/dadazunzhe/p/11340891.html
Copyright © 2020-2023  润新知