• 装饰器相关知识


    装饰器的相关知识点
    1. 装饰器的原理及为什么要用装饰器
    装饰器原理:在不修改源代码,不修改调用方式的基础上扩展新功能
     
    开放封闭原则:软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的。也就是说我们必须找到一种解决方案:能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能。
     
    1. 装饰器的基本用法
    def outer(func):
       def inner(*args,**kwargs):
           res=func(*args,**kwargs)
           return res
       return inner
     
    1. 带参数的装饰器
    再包上一层,函数的参数可以为一个,也可为多个
    def auth(engine):
       def auth2(func):
           def wrapper(*args,**kwargs):
               if engine=='file':
                    if current_user['username']:
                        print('login already')
                        res=func(*args,**kwargs)
                        return res
                    uname=input('username>>: ').strip()
                    pwd=input('password>>: ').strip()
                    if uname=='egon' and pwd=='123':
                       print('login successfully')
                       current_user['username']=uname
                        res=func(*args,**kwargs)
                        return res
                    else:
                        print('wrong username or password')
               elif engine=='mysql':
                    print('based on mysql')
               elif engine=='idap':
                    print('based on ldap')
           return wrapper
       return auth2
     
    @auth('mysql')
    def f():
       pass
     
    f()
     
    1. 被装饰的函数有返回值怎么处理
    res=func(*args,**kwargs)
    return res
     
    1. 多个装饰器的执行顺序
    叠加多个装饰器,上面的装饰器的作用为: 下方装饰器+原函数

    装饰器函数的执行顺序是分为定义阶段和执行阶段的,装饰器函数在被装饰函数定义好后立即执行

    • 在函数定义阶段:执行顺序是从最靠近函数的装饰器开始,自内而外的执行
    • 在函数执行阶段:执行顺序由外而内,一层层执行


     
    6. 装饰类的装饰器
    @classmethod
    将被装饰的函数变成绑定给类的方法;应该由类来调用,会主动将类作为第一个参数传入
     
    @staticmethod
    将被装饰的函数变成非绑定方法;既不跟类绑定,也不跟对象绑定,这意味着谁都能用;谁来用都是一个普通函数,也就是说没有自动传值的特性了
     
    7、 装饰器修复技术
    from functools import wraps   (强烈推荐写上这一行)
    def wrapper(func):
    # 装饰器修复技术
        @wraps(func)
        def inner(*args, **kwargs):
            print("start")
            ret = func(*args, **kwargs)
            print("end")
            return ret
        return inner
     
    @wrapper
    def f(*args, **kwargs):
        """
        这是一个测试装饰器的函数,没什么其他的用法
        :param args:
        :param kwargs:
        :return:
        """
        print("2018-06-04")
     
    f()
    print(f.__doc__)   # 如果不加装饰器的修复技术,打出的inner函数的__doc__
    print(f.__name__)  # 如果不修复,打出的是inner

  • 相关阅读:
    spring @Transactional 事务注解
    vue 父子组件的方法调用
    spring boot使用TestRestTemplate集成测试 RESTful 接口
    JS实现网站内容的禁止复制和粘贴、另存为
    vue把localhost改成ip地址无法访问—解决方法
    spring mvc spring boot 允许跨域请求 配置类
    JIRA安装过程中链接mysql的问题!
    vue开发中v-for在Eslint的规则检查下出现:Elements in iteration expect to have 'v-bind:key' directives
    Linux进程启动/指令执行方式研究
    反弹Shell原理及检测技术研究
  • 原文地址:https://www.cnblogs.com/maojiang/p/9135547.html
Copyright © 2020-2023  润新知