为什么在fn内要把r return啊,目的不是打印时间吗
def fn(*args,**kw): t1 = time.time() r = f(*args,**kw) t2 = time.time() print 'call %s() in %fs' % (f.__name__,(t2 - t1)) return r
def fn(*args,**kw): t1 = time.time() r = f(*args,**kw) t2 = time.time() print 'call %s() in %fs' % (f.__name__,(t2 - t1)) return r
2016-01-25
我说一下我的理解吧,你的代码不全,我补全了说一下。
def performance(f): def fn(*args, **kw): t1 = time.time() r = f(*args, **kw) t2 = time.time() print 'call %s() in %fs' % (f.__name__, (t2 - t1)) return r return fn @performance def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1)) print factorial(10)
这个代码整个的调用只有最后一句 print factorial(10)。
回到定义,@performance相当于factorial = performance(factorial)
我们再看performance的定义,他在内部定义了一个函数fn,fn的返回值是一个数值r,r是最开始传入的函数f的计算结果,其类型是int。而performance的返回值是fn,是一个函数,其type是function,这个和r的type不一样,这点很重要。因为python的闭包特性,返回值为函数时会创建一个闭包,就是说函数运行完后会保存相应的环境,不会当时销毁(关于闭包我大概是这么理解的,可能有误)。因此我们就保存下来了最开始传入的函数f的运行结果r。
最后,再看一遍运行过程。factorial(10)被包装成performance(factorial),然后运行performance函数,参数是原始的factorial(10),然后是一大段fn的定义,我们先不管。performance的作用是返回fn,此时fn运行,返回一个结果r,然后r被print打印出来。大概是这么个流程,因此,如果不返回r,最后哦的print factorial(10)不会有结果。
一点浅见。
这是一个装饰器,浅见是只装饰不改变本质,在未经装饰的factorial中有返回值,经performance高级函数装饰过后,一般情况下不要删除factorial即原函数的任何行为,也就是说未装饰的factorial行为要是@performance装饰过后的行为的子集,既然在factorial中有返回值,则要把这个返回值再经装饰器吐出,这也就是return r的原因,是为了保持行为的一致性。再解释一点,return fn,这个就是闭包了这个return是performance的return,也就是这个装饰器高阶函数的返回值,而return r是fn的return返回值,fn只是个普通的内建函数而已。之所以要return fn,目的是延迟factorial的执行,保存定义环境,??至于这算不算多态,还需学习研究??,对于装饰器更主要的目的是把丰富原函数factorial的一系列行为包装返回,??达到封装行为、动作的目的???。当然,函数是可以没有return语句的,即没有return r语句也是正确的,???这算高级装饰吗???,好像一所普通户型装饰出豪宅的感觉??第一次发帖,纯为了打字娱乐,请喷吧!!!
举报