24, Python has the participation decorator

First, pre-knowledge

1.1 No reference decorator template

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 decorator 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

Second, there is a reference decorator

2.1 has achieved participation decorator

If no arguments on the basis of the decorator, and then used to be added to achieve a target authentication function decorated decoration, a need to package in one deco external auth function, one designed to accept an additional parameter, thus ensures that No matter how many layers can refer to in the auth function.

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 There decorator template parameters

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

Guess you like

Origin www.cnblogs.com/zuiyouyingde/p/12559496.html