zoukankan      html  css  js  c++  java
  • 装饰器(1)

    一、定义

    装饰器就是闭包函数的一种应用场景

    装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
    强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
    装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

    二、作用

    开放封闭原则:对修改封闭,对扩展开放

    三、装饰器的使用

    import time
    def timmer(func):
        def wrapper(*args,**kwargs):
            start_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print('run time is %s' %(stop_time-start_time))
            return res
        return wrapper
    
    @timmer
    def foo():
        time.sleep(3)
        print('from foo')
    foo()
    无参装饰器
    def auth(driver='file'):
        def auth2(func):
            def wrapper(*args,**kwargs):
                name=input("user: ")
                pwd=input("pwd: ")
    
                if driver == 'file':
                    if name == 'egon' and pwd == '123':
                        print('login successful')
                        res=func(*args,**kwargs)
                        return res
                elif driver == 'ldap':
                    print('ldap')
            return wrapper
        return auth2
    
    @auth(driver='file')
    def foo(name):
        print(name)
    
    foo('egon')
    
    有参装饰器
    有参装饰器
    def auth(x,engine = "file"):
        def outter(func):
            def wrapper(*args, **kwargs):
                x
                name = input("username>: ").strip()
                pwd = input("password>: ").strip()
    
                if engine == "file":
                    if name == "egon" and pwd == "123":
                        print('login successful'.center(50,'='))
    
                        res = func(*args, **kwargs)
                        return res
                    else:
                        print('username or password error')
                elif engine == "mysql":
                    print("基于mysql的认证")
                elif engine == "ldap":
                    print("基于ldap的认证")
                else:
                    print('engine不存在')
            return wrapper
        return outter
    
    @auth(11,"file")  # @outter函数的内存地址  # index=outter函数的内存地址(index函数的内存地址)
    def index():
        print('from index')
    @auth(11,"mysql")
    def home(name):
        print('welcome %s to home page' %name)
    
    # index=auth(index,"file")
    # home=auth(index,"ldap")
    
    index()
    home("egon")
    
    # 模板
    
    def outter2(x):
        def outter1(func):
            def wrapper(*args, **kwargs):
                res = func(*args, **kwargs)
                return res
    
            return wrapper
        return outter1
    
    
    @outter2(x=1)
    def index():
        pass
    有参装饰器示例

    四、装饰器语法

    #被装饰函数的正上方,单独一行
            @deco1
            @deco2
            @deco3
            def foo():
                pass
    
            foo=deco1(deco2(deco3(foo)))
    

    五、装饰器补充

    from functools import wraps
    
    def deco(func):
        @wraps(func) #加在最内层函数正上方
        def wrapper(*args,**kwargs):
            return func(*args,**kwargs)
        return wrapper
    
    @deco
    def index():
        '''哈哈哈哈'''
        print('from index')
    
    print(index.__doc__)
    

    六、叠加多个装饰器

    # 叠加多个装饰器
    # 1. 加载顺序(outter函数的调用顺序):自下而上
    # 2. 执行顺序(wrapper函数的执行顺序):自上而下
    
    def outter1(func1): #func1=wrapper2的内存地址
        print('加载了outter1')
        def wrapper1(*args,**kwargs):
            print('执行了wrapper1')
            res1=func1(*args,**kwargs)
            return res1
        return wrapper1
    
    def outter2(func2): #func2=wrapper3的内存地址
        print('加载了outter2')
        def wrapper2(*args,**kwargs):
            print('执行了wrapper2')
            res2=func2(*args,**kwargs)
            return res2
        return wrapper2
    
    def outter3(func3): # func3=最原始的那个index的内存地址
        print('加载了outter3')
        def wrapper3(*args,**kwargs):
            print('执行了wrapper3')
            res3=func3(*args,**kwargs)
            return res3
        return wrapper3
    
    
    
    @outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
    @outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
    @outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
    def index():
        print('from index')
    
    print('======================================================')
    index()
    
    示范代码
    范例1
    # def deco1(func1):  # func1 = wrapper2的内存地址
    #     def wrapper1(*args, **kwargs):
    #         print('====>wrapper1')
    #         res1 = func1(*args, **kwargs)
    #         return res1
    #     return wrapper1
    #
    # def deco2(func2):  # func2 = wrapper3的内存地址
    #     def wrapper2(*args, **kwargs):
    #         print('====>wrapper2')
    #         res2 = func2(*args, **kwargs)
    #         return res2
    #     return wrapper2
    #
    # def deco3(func3):  # func3 = index函数的内存地址
    #     def wrapper3(*args, **kwargs):
    #         print('====>wrapper3')
    #         res3 = func3(*args, **kwargs)
    #         return res3
    #     return wrapper3
    #
    # # 加载/得到wrapper函数的顺序是自下而上的
    # # 我们运行wrapper函数的顺序是:
    #
    #         # index=wrapper1的内存地址
    # @deco1  # deco1(wrapper2的内存地址) => wrapper1的内存地址
    # @deco2  # deco2(wrapper3的内存地址) => wrapper2的内存地址
    # @deco3  # deco3(index函数的内存地址) => wrapper3的内存地址
    # def index():
    #     print('from index')
    #
    # # print(index)
    # res=index()
    # """
    # ====>wrapper1
    # ====>wrapper2
    # ====>wrapper3
    # from index
    # """
    import time
    
    def timmer(func):
        def wrapper(*args,**kwargs):
            start=time.time()
            res=func(*args,**kwargs)
            stop=time.time()
            print("run time is : %s" %(stop - start))
            return res
        return wrapper  # 千万不要加括号
    
    def auth(x,engine = "file"):
        def outter(func):
            def wrapper(*args, **kwargs):
                x
                name = input("username>: ").strip()
                pwd = input("password>: ").strip()
    
                if engine == "file":
                    if name == "egon" and pwd == "123":
                        print('login successful'.center(50,'='))
    
                        res = func(*args, **kwargs)
                        return res
                    else:
                        print('username or password error')
                elif engine == "mysql":
                    print("基于mysql的认证")
                elif engine == "ldap":
                    print("基于ldap的认证")
                else:
                    print('engine不存在')
            return wrapper
        return outter
    
    @auth(111,"file")
    @timmer
    def index():
        print("index=====>")
        time.sleep(3)
    
    index()
    示例2

     

  • 相关阅读:
    异常
    动态链接库与静态链接库的区别
    OpenBLAS 安装与使用
    Eigen 优化技巧
    C++读取保存为二进制的 numpy 数组
    Sublime Text Windows版使用Conda环境
    Repeater 时间格式化
    C#与js的各种交互
    js 实现精确加减乘除
    常用正则表达式
  • 原文地址:https://www.cnblogs.com/datatool/p/13458190.html
Copyright © 2011-2022 走看看