美文网首页
Python 带参数的装时器

Python 带参数的装时器

作者: lighkLife | 来源:发表于2017-01-16 16:16 被阅读0次

    摘录整理于imooc

    1. 一个带参数的decorator例子

    例子是根据 @performance('time_type')携带的时间类型来输出所装饰的函数factorial的执行时间。

    import time
    import functools
    from past.builtins.noniterators import reduce
    
    def performance(unit):
        def perf_decorator(f):
            # @functools.wraps应该作用在返回的新函数上。
            @functools.wraps(f)
            def wrapper(*args, **kw):
                t1 = time.time()
                r = f(*args, **kw)
                t2 = time.time()
                t = (t2 - t1) * 1000 if unit == 'ms' else (t2 - t1)
                print('call %s() in %f %s' % (f.__name__, t, unit))
                return r
            return wrapper
        return perf_decorator
    
    
    @performance('ms')
    def factorial(n):
        return reduce(lambda x, y: x * y, range(1, n + 1))
    
    factorial(10000)
    print(factorial.__name__)
    

    2.代参数的decorator为什么要包三层(三阶)?

    # 为什么包三层(三阶)
    @log('DEBUG')
    def my_func():
        pass
    # 把上面的定义翻译成高阶函数的调用,就是:
    
    my_func = log('DEBUG')(my_func)
    # 上面的语句看上去还是比较绕,再展开一下:
    
    log_decorator = log('DEBUG')
    my_func = log_decorator(my_func)
    # 上面的语句又相当于:
    
    log_decorator = log('DEBUG')
    @log_decorator
    def my_func():
        pass
    # 所以,带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数:
    
    def log(prefix):
        def log_decorator(f):
            def wrapper(*args, **kw):
                print('[%s] %s()...' % (prefix, f.__name__))
                return f(*args, **kw)
            return wrapper
        return log_decorator
    
    @log('DEBUG')
    def test():
        pass
    print(test())
    

    简而言之,最外层负责把decorator的参数DEBUG传进来,既然decorator携带的参数已经传进来,那么剩下的中间层和里层就是一个不带参的decorator的语法糖。反之而推,要多携带参数,肯定是需要多加一阶。

    相关文章

      网友评论

          本文标题:Python 带参数的装时器

          本文链接:https://www.haomeiwen.com/subject/zklpbttx.html