简体   繁体   English

Python 装饰器 - 斐波那契递归函数 - 意外输出

[英]Python Decorator - Fibonacci Recursive Function - Unexpected Output

I tried to play with using a decorator on a recursive function such as the one that calculates the nth Fibonacci number.我尝试在递归函数上使用装饰器,例如计算第nth斐波那契数的函数。

Below is the code I wrote:下面是我写的代码:

class FibList:
# decorator will return a list of fibonacci numbers from 0 to n.
    def __init__(self, func):
        self.func = func

    def __call__(self, *args):
        return [self.func(x) for x in range(args[0])]

@FibList
def fibonacci(n):
    # function will return nth fibonacci number
    if n < 2:
        return n
    else:
        return fibonacci(n-2) + fibonacci(n-1)

if __name__ == "__main__":
    a = fibonacci(4)
    print(a)

The output for a looks like this: [0, 1, [0], [0, 0, 1]] . a的输出如下所示: [0, 1, [0], [0, 0, 1]] But, I am expecting the output looks like this: [0, 1, 1, 2]但是,我希望输出看起来像这样: [0, 1, 1, 2]

I am really having a hard time understanding what is going on inside the decorated fibonacci function.我真的很难理解装饰的fibonacci那契函数内部发生了什么。

If anyone can help me to clarify such strange behavior, I will be much appreciated it.如果有人可以帮助我澄清这种奇怪的行为,我将不胜感激。 Thank you.谢谢你。

Your issue is caused by multiple recursion.您的问题是由多次递归引起的。

If you run the debugger and check each call of the recursive function, you will notice that the if-block returns the number correctly.如果您运行调试器并检查递归函数的每次调用,您会注意到 if 块正确地返回了数字。 That's why the first two numbers in your result list are correct.这就是为什么结果列表中的前两个数字是正确的。 But as soon as it reaches the else-block, it will call the __call__ method of the Class with n-2 and n-1 respectively and thus create a new sublist inside of your result list.但是一旦它到达 else 块,它将分别调用具有n-2n-1的类的__call__方法,从而在结果列表中创建一个新的子列表。

When `n==2` the result would become:
fibonacci(n-2) -> __call__(self, 0) --> []
fibonacci(n-1) -> __call__(self, 1) --> [0]
return fibonacci(n-2) + fibonacci(n-1) --> [] + [0] = [0]

For n==3 you would get the last sublist [0,0,1]对于n==3你会得到最后一个子列表[0,0,1]

You need to find a way to prevent this multi-recursive call.您需要找到一种方法来防止这种多递归调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM