缘起,在人群中,我看见你---------------装饰器

装饰器

装饰器的定义(what why how)

1.什么是装饰器
	装饰器就是装饰某一个东西的工具
2.为什么要用装饰器
	因为在源函数代码不改变调用方法&原代码给原函数添加新功能,装饰器是最好的解决工具
3.怎么用装饰器
	详见下面

装饰器的实现思路

"""
	现有一个原函数index,想要为其添加一个时间差的功能,我们应该怎么做呢
"""

# 方案一  这就已经修改了他的原代码了
	import time


    def index(x):
        start_time = time.time()
        print(f'welcome to index {x}')
        time.sleep(3)
        print(time.time() - start_time)

    index(1)
# 方案二 没有修改原函数的代码&调用,但是代码冗余
    def index(x):
        print(f'welcome to index {x}')
        time.sleep(3)


    start_time = time.time()
    index(1)
    print(time.time() - start_time)

    start_time = time.time()
    index(1)
    print(time.time() - start_time)


# 方案三 解决了代码冗余问题,但是原函数的调用我们修改了,而且wrapper写死了,只能调用index
    def index(x):
        print(f'welcome to index {x}')
        time.sleep(3)


    def wrapper():
        start_time = time.time()
        index(1)
        print(time.time() - start_time)


    wrapper()


# 方案四 我们先搞定调用index函数写死问题
    def index(x):
        print(f'welcome to index {x}')
        time.sleep(3)


    def outter(func):
        def wrapper():
            start_time = time.time()
            func(1)
            print(time.time() - start_time)

        return wrapper


    index = outter(index)
    index()


# 方案五  然后在搞定index函数参数问题
    def index(x):
        print(f'welcome to index {x}')
        time.sleep(3)


    def outter(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            func(*args, **kwargs)
            print(time.time() - start_time)

        return wrapper


    index = outter(index)
    index(11)


# 方案六  在搞定index返回值的问题,这样就把wrapper伪装成index伪装的很好了
    def index(x):
        print(f'welcome to index {x}')
        time.sleep(3)
        return 123


    def outter(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            print(time.time() - start_time)
            return res

        return wrapper


    index = outter(index)
    res = index(11)
	print(res)


# 方案七 在让wrapper更像index一点
    def index(x):
        """
        这是index的配置信息
        """

        print(f'welcome to index {x}')
        time.sleep(3)
        return 123


    def outter(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            print(time.time() - start_time)
            return res

        wrapper.__name__ = index.__name__
        wrapper.__doc__ = index.__doc__
        return wrapper


    index = outter(index)
    res = index(11)
    print(res)


# 语法糖
    def outter(func):
        from functools import wraps
        @wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            print(time.time() - start_time)
            return res

        return wrapper


    @outter
    def index(x):
        """
        这是index的配置信息
        """

        print(f'welcome to index {x}')
        time.sleep(3)
        return 123


    res = index(11)
    print(res)

装饰器的总结模板

# 无参装饰器
def outter(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper

# 有参装饰器
def outter(x):
    def foo(func):
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res
        return wrapper
   	return foo

多个装饰器

import time


def deco1(func):
    print('----deco1')

    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        print(time.time() - start_time)
        return res

    return wrapper()


def deco2(func):
    print('----deco2')

    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        print(time.time() - start_time)
        return res

    return wrapper()


@deco1
@deco2
def index(x):
    print(f'{x}')
'''
	当多个装饰器叠加的时候 例如这样是先从上而下去执行,但是返回值则是从下而上的去返回 所以deco2的返回值是在deco1,deco1的返回值是在真正的index上
'''

有参装饰器

def login():
    name = input('name is :').strip()
    pwd = input('pwd is :').strip()

    if name == 'ycc' and pwd == '123':
        print('login successful')
    else:
        print('name or pwd error')

def auth(db_type):
    def deco(func):
        def wrapper(*args,**kwargs):

            if db_type == 'file':
                login()
                print('基于文件验证')
                # res = func(*args,**kwargs)
                # return res
            elif db_type == 'mysql':
                login()
                print('基于数据库验证')
                # res = func(*args, **kwargs)
                # return res

            elif db_type == 'ldap':
                login()
                print('基于ldap验证')
                # res = func(*args, **kwargs)
                # return res
            res = func(*args, **kwargs)
            return res
        return wrapper
    return deco


@auth(db_type='file')
def index(x, y):
    print(x, y)


@auth(db_type='mysql')
def home(name):
    # print('welcome %s to home page'%name)
    print(f'welcome {name} to home page')
    return name


@auth(db_type='ldap')
def transfer():
    print('transfer')


index(1, 2)
name = home('ycc')
print(name)
posted @ 2021-07-01 15:37  Ame林汀  阅读(80)  评论(0)    收藏  举报