Python 带参数的装时器

摘录整理于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的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pa...
    linheimx阅读 637评论 0 4
  • 要点: 函数式编程:注意不是“函数编程”,多了一个“式” 模块:如何使用模块 面向对象编程:面向对象的概念、属性、...
    victorsungo阅读 1,562评论 0 6
  • Python进阶框架 希望大家喜欢,点赞哦首先感谢廖雪峰老师对于该课程的讲解 一、函数式编程 1.1 函数式编程简...
    Gaolex阅读 5,523评论 6 53
  • 22年12月更新:个人网站关停,如果仍旧对旧教程有兴趣参考 Github 的markdown内容[https://...
    tangyefei阅读 35,223评论 22 257
  • 本文为《爬着学Python》系列第四篇文章。从本篇开始,本专栏在顺序更新的基础上,会有不规则的更新。 在Pytho...
    SyPy阅读 2,519评论 4 11