为了账号安全,请及时绑定邮箱和手机立即绑定

不太理解这个装饰器的运行过程

import time

def performance(unit):
    def perf_decorator(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))

print factorial(10)

请问ms参数首先返回在哪里?是#处吗?

如果是,接下来该执行哪一步?

2019-07-30 源自:python进阶 2-13 239 浏览 3 回答

最佳回答

2019-08-04

当执行factorial(10)时,会先去执行注解,也就是@performance('ms')。因为带参数,所以会先执行def performance(unit),把字符串ms传到unit,然后会再把被注解的函数作为参数执行def perf_decorator(f),至此注解部分就已经执行完毕了。接下来就是执行函数def factorial(n),也就是def wrapper(*args, **kw),然后该计时的计时,在计时的过程中就会执行真正的函数f(*args, **kw),并在最后return返回值,也就是print打印出的东西,流程就是这样。

但是当执行def factorial(n)即factorial(10)时,实际上执行的函数已经不是factorial函数了,被替换成了wrapper函数,可以在factorial函数内打印下函数名:

@performance('ms')
def factorial(n):
    print 'function name is %s' % factorial.__name__
    return reduce(lambda x,y: x*y, range(1, n+1))

会发现打印出的是wrapper。在2-14中也有解释

weixin_慕粉0189013 (提问者)

好的 谢谢

#1 2019-08-05 回复

装饰器是对函数的一种包装,通过一个高阶函数包装原函数,扩充其功能而不改变其原本代码。调用peformance函数接收字符串‘ms’后完成了内部函数的定义并返回了函数对象perf_decorator。所以@performance('ms')其实是@perf_decorator。在调用factorial时,‘ms’参数才传入#处

2019-08-04
回复 0

好的 谢谢

2019-08-05
回复 0

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信