Python装饰器

2021-01-29  本文已影响0人  lk_erzanml
#它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

# 1.需求1,计算函数执行时间

def compute_time(func):
    from functools import wraps
    import time
    @wraps(func)
    def wrapper(*args,**kwargs):
        """
        I am wrapper!
        :param args:
        :param kwargs:
        :return:
        """
        start_time=time.time()
        func(*args,**kwargs)
        print("总消耗时间:{}s".format(time.time()-start_time))
    return wrapper

#2.校验参数格式,必须大于0,小于100

def jiaoyan_args(func):
    from functools import wraps
    @wraps(func)
    def wrapper(*args,**kwargs):
        n=args[0]
        if n>100 or n<0:
            return "输入错误"
        return func(*args,**kwargs)
    return wrapper


#带参数的装饰器
import time
import functools


def log(kind):
    def add_log(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            end_time = time.time()
            print('<%s> [%s] 函数名:%s,运行时间:%.6f,运行返回值的结果'
                  ':%d' % (kind, time.ctime(), func.__name__,
                           end_time - start_time, res))
            return res

        return wrapper

    return add_log


@log('debug')
def add():
    time.sleep(1)
    return 1 + 1


@log('debug')
def sub():
    time.sleep(1)
    return 2 - 1

#类装饰器
import time
class Foo():
    def __init__(self, func):    # 初始化函数中传入函数对象的参数
        self._func = func
    def __call__(self):    # 定义__call__方法,直接实现装饰功能
        start_time = time.time()
        self._func()
        end_time = time.time()
        print('花费了 %.2f' % (end_time - start_time))

@Foo  # bar=Foo(bar)
def bar():
    print('bar函数的执行时间为:')
    time.sleep(2.5)

bar()    # bar=Foo(bar)(),没有嵌套关系了,直接执行Foo的 __call__方法,实现装饰功能











if __name__=="__main__":

    @compute_time
    def nead_something(n):
        """
        返回一个数的平方
        :param n:
        :return:
        """
        print(n**2)
        return n**2

    # nead_something(10)
    # print(nead_something.__name__)#被改变了
    # print(nead_something.__doc__)
    #加了语法糖@wraps(func)就不改变__name__和__doc__了

    @jiaoyan_args
    def nead_something1(n):
        """
        返回一个数的平方
        :param n:
        :return:
        """
        return n**2

    # print(nead_something1(1001))


    # print(add())
    # print(sub())

上一篇 下一篇

猜你喜欢

热点阅读