• 24、Python之有参装饰器


    一、前置知识

    1.1 无参装饰器模板

    def outter(func):
        def wrapper(*args,**kwargs):
            # 1、调用原函数
            # 2、给原函数增加新的功能
        	res=func(*args,**kwargs)
        	# 3、给原函数增加新的功能
        	return res
        return wrapper
    
    @outter # index=outter(index)
    def index(x,y):
        """这个是主要功能"""
        print(x,y)
        
    print(index) # <function outter.<locals>.wrapper at 0x0000027FF77B20D0>
    print(index.__name__) # wrapper,实际上还是wrapper函数
    print(help(index)) # wrapper的文档注释如下:
    '''
    Help on function wrapper in module __main__:
    
    wrapper(*args, **kwargs)
        这个是主要功能
    
    None
    '''
    # 经装饰之后的函数,还是没有完全伪装的跟原函数一样,需要继续优化
    

    1.2 装饰器wraps

    #偷梁换柱,即将原函数名指向的内存地址偷梁换柱成wrapper函数,所以应该将wrapper做的跟原函数一样才行
    
    from functools import wraps  # 引入functools模块下的装饰器wraps
    
    def outter(func):
        @wraps(func)  # functools模块下提供的装饰器wraps,可以实现保留原函数属性的操作
        def wrapper(*args,**kwargs):
            # 1、调用原函数
            # 2、给原函数增加新的功能
        	res=func(*args,**kwargs)
        	# 3、给原函数增加新的功能
        	return res
        return wrapper
    
    

    二、有参装饰器

    2.1 有参装饰器的实现

    若在无参装饰器的基础上,再实现一个用来为被装饰对象添加认证功能的装饰器,需要在deco外部再包一层函数auth,用来专门接受额外的参数,这样便保证了在auth函数内无论多少层都可以引用到。

    def auth(db_type):
        def deco(func):
            def wrapper(*args, **kwargs):
                name = input('your name>>>: ').strip()
                pwd = input('your password>>>: ').strip()
    
                if db_type == 'file':
                    print('基于文件的验证')
                    if name == 'egon' and pwd == '123':
                        res = func(*args, **kwargs)  # index(1,2)
                        return res
                    else:
                        print('user or password error')
                elif db_type == 'mysql':
                    print('基于mysql的验证')
                elif db_type == 'ldap':
                    print('基于ldap的验证')
                else:
                    print('不支持该db_type')
            return wrapper
        return deco
    
    
    @auth(db_type='file')  # @deco # index=deco(index) # index=wrapper
    def index(x, y):
        print('index->>%s:%s' % (x, y))
    
    @auth(db_type='mysql')  # @deco # home=deco(home) # home=wrapper
    def home(name):
        print('home->>%s' % name)
    
    
    @auth(db_type='ldap')  # 账号密码的来源是ldap
    def transfer():
        print('transfer')
    
    index(1, 2)
    home('egon')
    transfer()
    

    2.2 有参装饰器模板

    def 有参装饰器(x,y,z):
        def outter(func):
            def wrapper(*args, **kwargs):
            	# 1、为其增加新功能
                res = func(*args, **kwargs)
                return res
                # 2、调用原函数后为其增加其他新功能
            return wrapper
        return outter
    
    @有参装饰器(1,y=2,z=3)
    def 被装饰对象():
        pass
    
  • 相关阅读:
    QFramework Pro 开发日志(一)随便写点啥,3 月开始整活了。
    QFramework Pro 开发日志(六)一键生成类图功能介绍
    QFramework Pro 开发日志(二)为啥要搞 Pro
    乡亲们,我们创建了 Dapr 中文交流频道
    学大数据要考什么证书吗?2022软考备考群已成立!
    元数据管理为什么需要统一的元模型?
    美团外卖实时数仓方案整理
    巧用 Base62 解决字段太短的问题
    千万级支付对账系统怎么玩(下篇)?
    千万级支付对账系统怎么玩(上篇)?
  • 原文地址:https://www.cnblogs.com/zuiyouyingde/p/12559496.html
Copyright © 2020-2023  润新知