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

为什么在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


正在回答

3 回答

我说一下我的理解吧,你的代码不全,我补全了说一下。

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)不会有结果。

一点浅见。

5 回复 有任何疑惑可以回复我~
#1

bestkayle 提问者

非常感谢,我之前把装饰器和函数分开想了。。
2016-03-26 回复 有任何疑惑可以回复我~
#2

你灬近在远方

没太明白为什么performance要返回fn。是不是可以理解成fn在performance的内部,需要performance先返回fn,也就是先把fn拿出来,然后再运行fn?也就是说在performance中其实是先运行 return fn 然后再运行fn函数的?
2016-04-14 回复 有任何疑惑可以回复我~

这是一个装饰器,浅见是只装饰不改变本质,在未经装饰的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语句也是正确的,???这算高级装饰吗???,好像一所普通户型装饰出豪宅的感觉??第一次发帖,纯为了打字娱乐,请喷吧!!!

2 回复 有任何疑惑可以回复我~

高阶函数在原有函数的基础上,又增加了一些其他的功能,比如打印时间。当调用此高阶函数的时候,除了计算出运行时间外,也会根据原函数已有的功能去调用原函数,返回原函数的值。

@performance

def factorial(n):

    return reduce(lambda x,y: x*y, range(1, n+1))


print factorial(10)

上面这个除了计算出运行时间外,还要求获得factorial(10)的返回值

0 回复 有任何疑惑可以回复我~
#1

bestkayle 提问者

thanks
2016-03-26 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
python进阶
  • 参与学习       255665    人
  • 解答问题       2949    个

学习函数式、模块和面向对象编程,掌握Python高级程序设计

进入课程

为什么在fn内要把r return啊,目的不是打印时间吗

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信