2016-07-23 148 views
1

给出以下代码,我不明白为什么f和fib行为不同。 从巴克利所采取的示例cs61a当然Python高阶函数

def fib(n): 
    if n==1 or n==0: 
     return n 
    else: 
     return fib(n-1) + fib(n-2) 

def decor(f): 
    def counted(*args): 
     counted.call_count += 1 
     return f(*args) 
    counted.call_count = 0 
    return counted 

当我加载代码到解释器我得到这样的输出:

>>> fib(6) 
8 
>>> f = decor(fib) 
>>> fib = decor(fib) 
>>> # f and fib are both vars that represents a decorated fib function 

>>> f(6) 
8 
>>> f.call_count # why 1 ??? 
1 
>>> 
>>> fib(6) 
8 
>>> fib.call_count # 49 calls, that's fine 
49 

回答

2

f.call_count是1,因为f呼叫fib,然后fib递归调用自身来计算结果。在这整个过程中,f只被调用一次。

但是当你做fib = decor(fib),你覆盖fib功能在全球范围内,所以从那一刻起fib会递归调用装饰fib

0

您将要覆盖fib然后f电话fib,而不是本身:在0x7fa844639758

=== f === 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
8 
1 
=== fib === 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
fib is: <function counted at 0x7fa844639758> 
8 
49 

注意fib is功能的所有时间:

def fib(n): 
    if n==1 or n==0: 
     return n 
    else: 
     print("fib is: " + repr(fib)) 
     return fib(n-1) + fib(n-2) 

def decor(f): 
    def counted(*args): 
     counted.call_count += 1 
     return f(*args) 
    counted.call_count = 0 
    return counted 



f = decor(fib) 
fib = decor(fib) 

print("=== f ===") 
print(f(6)) 
print(f.call_count) 

print("=== fib ===") 
print(fib(6)) 
print(fib.call_count) 

当我运行这个输出。

+0

是否意味着fib在全球范围内是相同的?我假设绑定fib再装饰(纤维)返回一个新的功能,这是不相关的'旧'纤维,正如f所做的......是什么特定于python?让我想我想念一些基本的语言理解。似乎很明显,rebind fib应该返回f – chenchuk