python3装饰器-进阶

一、wraps

作用:优化装饰器

from functools import wraps     # 导入wraps


def wrapper(f):
    @wraps(f)       # wraps的语法糖
    def inner(*args, **kwargs):
        ret = f(*args, **kwargs)
        return ret
    return inner


@wrapper
def f1():
    print("Hello, World!")
    return 'Hi'


res = f1()
print(res)
print(f1.__name__)      # 查看字符串格式的函数名,打印的函数名inner->f1

二、带参数的装饰器

实质:嵌套调用,三层嵌套函数

from functools import wraps
import time
flag = True


def wrapper_out(is_flage):
    def wrapper(func):
        """
        flag为True时函数被装饰器装饰
        flag为FLASE时函数正常被调用
        :param func: 
        :return: 
        """
        @wraps(func)
        def inner(*args, **kwargs):     # 聚合
            if is_flage:
                start = time.time()
                ret = func(*args, **kwargs)    # 打散
                end = time.time()
                print(end-start)
                return ret
            else:
                ret = func(*args, **kwargs)
                return ret
        return inner
    return wrapper


@wrapper_out(flag)      # @wrapper_out()->@wrapper->f1=wrapper(f1) 调用wrapper_out(flag)函数,return wrapper
def f1():
    time.sleep(1)
    print("Hello, World")
    return 'joker'


ret = f1()
print(ret)

三、多个装饰器装饰一个函数

from functools import wraps


def wrapper1(func):     # func->f1
    @wraps(func)
    def inner1(*args, **kwargs):
        print("wrapper1,before")        # 2
        ret = func(*args, **kwargs)     # 3, f1()
        print("wrapper1,after")         # 4
        return ret      # ret is f1()的返回值,现在是执行inner1()的返回值
    return inner1


def wrapper2(func):     # func->inner1
    @wraps(func)
    def inner2(*args, **kwargs):
        print("wrapper2,before")        # 1
        ret = func(*args, **kwargs)     # inner1()
        print("wrapper2,after")         # 5, 执行完inner1()
        return ret      # ret is inner1()的返回值即f1()的返回值,现在是执行inner2()的返回值
    return inner2


@wrapper2       # f1=wrapper2(inner1)
@wrapper1       # f1=wrapper1(f1)->f1=inner1
def f1(a):
    print("Hello")
    return a


"""
f1指向inner2的内存地址,f1()->inner2(),f1()的返回值是inner2()的返回值,也就是f1()函数自身的返回值
"""
ret = f1(2)
print(ret)
"""
结果:
wrapper2,before
wrapper1,before
Hello
wrapper1,after
wrapper2,after
2
"""

现象:

 

原文地址:https://www.cnblogs.com/wt7018/p/10835514.html