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

猜你喜欢

转载自www.cnblogs.com/zuiyouyingde/p/12559496.html