装饰器

装饰器

装饰器的推导过程

# 方案一:  代码冗余有,,如果很多地方调用index

# def index(x):
#     time.sleep(2)
#     print('welcome to %s' % x)
#
# start = time.time()
# index(11)
# stop = time.time()
# print(stop - start)


# 方案二:  写死了 改变了调用方式

# def index(x):
#     time.sleep(2)
#     print('welcome to %s' % x)
# def wrapper():
#     start = time.time()
#     index(11)
#     stop = time.time()
#     print(stop - start)
#
# wrapper()


# 方案三:  改变l调用方式

# def index(x):
#     time.sleep(2)
#     print('welcome to %s' % x)
# def wrapper(func):
#     start = time.time()
#     func(11)
#     stop = time.time()
#     print(stop - start)
#
# wrapper(index)


# 方案四:  参数写死了

# def index(x):
#     time.sleep(2)
#     print('welcome to %s' % x)
#
# def outer(func):
#     def wrapper():
#         start = time.time()
#         func(11)
#         stop = time.time()
#         print(stop - start)
#     return wrapper
#
# index = outer(index)
# index()


# 方案五:  装饰器完成
from functools import wraps


def outer(func):
    @wraps(func)                  # 这个呢就是可以把index函数的内置方法伪装的和wrapper一样
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)  # 接受的是func的返回值
        stop = time.time()
        print(stop - start)
        return res

    return wrapper  #outer的返回值
@outer   # index = outer(index的内存地址)  调用wrapper
def index(x):
    """
    qiufuwifiuqwf
    :param x:
    :return:
    """
    time.sleep(2)
    return 'welcome to %s' % x

多个装饰器

import time


def outer1(func1):
    print('加载了outer1')
    def wrapper1(*args, **kwargs):
        print('执行了wrapper1')
        res1 = func1(*args, **kwargs)
        return res1

    return wrapper1

def outer2(func2):
    print('加载了outer2')
    def wrapper2(*args, **kwargs):
        print('执行了wrapper2')
        res2 = func2(*args, **kwargs)
        return res2

    return wrapper2

def outer3(func3):
    print('加载了outer3')
    def wrapper3(*args, **kwargs):
        print('执行了wrapper3')
        res3 = func3(*args, **kwargs)
        return res3

    return wrapper3

@outer1
@outer2
@outer3
def index(x):
    time.sleep(2)
    print('welcome to %s' % x)

index('egon')

===================================>
加载了outer3
加载了outer2
加载了outer1
执行了wrapper1
执行了wrapper2
执行了wrapper3
welcome to egon
    
    
"""
整个运行过程:
   1.加载先是自下而上的,outer3(被装饰函数的index的内存地址) ---> 返回wraper3的内存地址
   2.outer2(wraper3的内存地址)---->返回wraper2的内存地址
   3.outer1(wraper2的内存地址)----->返回wraper1的内存地址
   4.index = wraper1的内存地址
   5.运行wraper2
   6.运行wraper3
"""

结论:
加载顺序(外层函数的调用顺序):自下而上
执行顺序(wraper的执行顺序):自上而下

有参装饰器

import time


def login_auth(type = None):
    def outer(func):
        def wrapper(*args, **kwargs):
            if type == 'file':
                res = func(*args, **kwargs)
                return res
            else:
                print('类型指定错误')

        return wrapper
    return outer


@login_auth('file')
def index(x):
    time.sleep(2)
    print('welcome to %s' % x)

index('egon')

@login_auth('mysql')
def home():
    pass

home()


"""
有参装饰器的本质就是在外层,加一层函数,闭包传参的方式
"""

无参装饰器模板

def outer(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper

有参装饰器模板

def auth(x):
    def outer(func):
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res
        return wrapper
    return outer
posted @ 2021-07-01 15:17  剧终cur  阅读(35)  评论(0)    收藏  举报