Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 打印出斐波那契级数_Python_Python 3.x_Closures_Fibonacci - Fatal编程技术网

Python 打印出斐波那契级数

Python 打印出斐波那契级数,python,python-3.x,closures,fibonacci,Python,Python 3.x,Closures,Fibonacci,我正在尝试编写一个简单的Python程序。它应该返回一个闭包,该闭包返回连续的斐波那契数: def fibGen(): n_1 = 0 n_2 = 0 n = 1 def fib(): if n_1 ==0 and n_2 ==0: n_1 = 1 return n else: n = n_1 + n_2 n_2 = n_1

我正在尝试编写一个简单的Python程序。它应该返回一个闭包,该闭包返回连续的斐波那契数:

def fibGen():
    n_1 = 0
    n_2 = 0 
    n = 1
    def fib():
        if n_1 ==0 and n_2 ==0:
            n_1 = 1
            return n
        else:
            n = n_1 + n_2
            n_2 = n_1
            n_1 = n  
            return n
    return fib

f = fibGen()
for i in range(0,10):
    print(f())
我在运行时遇到此错误:
UnboundLocalError:赋值前引用的局部变量“n_1”


编辑:在我原来的帖子中,我没有把
n=1
包含在
fibGen
的定义中,但实际上这是一个打字错误。无论如何,我仍然会得到相同的错误。

您不能修改封闭变量,n_1,n_2在
封闭空间中,而不是在函数空间中,这就是为什么您不能保存变量

使用
非本地
关键字

def fibGen():
    n_1 = 0
    n_2 = 0 
    def fib():
        nonlocal n_1, n_2
        if n_1 ==0 and n_2 ==0:
            n_1 = 1
            return n_1 # return `n_1` here not `n`
        else:
            n = n_1 + n_2
            n_2 = n_1
            n_1 = n  
            return n
    return fib

f = fibGen()
for i in range(0,10):
    print(f())

Python根据绑定行为在编译时确定变量的范围。如果指定一个名称,或将其用作
导入
目标(以及其他一些方法),则将该名称绑定到范围中

您正在绑定到
fib()
函数中的
n_1
n_2
;这两个都被分配到了。这使得这两个名称在
fib()
中成为本地名称,Python甚至不会查看周围的范围

您需要覆盖此行为,您可以使用:

nonlocal
明确地告诉编译器,您不希望它查看绑定行为,而是将名称视为闭包

接下来,在
if
测试的第一个分支中使用
n
,但在
else
分支之外的任何地方都没有定义它。无论如何,您应该在那里返回
1

def fibGen():
    n_1 = 0
    n_2 = 0 
    def fib():
        nonlocal n_1, n_2
        if n_1 ==0 and n_2 ==0:
            n_1 = 1
            return n_1
        else:
            n = n_1 + n_2
            n_2 = n_1
            n_1 = n  
            return n
    return fib
最后但并非最不重要的一点是,您可以使用元组分配交换两个变量,无需中介:

def fibGen():
    n_1 = 0
    n_2 = 0 
    def fib():
        nonlocal n_1, n_2
        if n_1 ==0 and n_2 ==0:
            n_1 = 1
        else:
            n_1, n_2 = n_1 + n_2, n_1
        return n_1
    return fib

我已经回顾了其中一些著名的算法,并想在Python中使用闭包分享我的斐波那契版本:

#!/usr/bin/env python

def fibonacci():
    a = 0
    b = 1

    def internal_fibonacci():
        nonlocal a, b
        a, b = b, a+b
        return a
    return internal_fibonacci


def main():
    f = fibonacci()
    for i in range(0,10):
        print("f(" + str(i) + ") => " + str(f()))


if __name__ == '__main__':
    main()

比这里提供的其他解决方案要优雅一点。

@Nearroyer66但我的答案很好地解释了代码中的问题。我知道,这就是为什么我“向上投票”取消了其他人的向下投票。有趣的是,这样的答案现在可以发布,而不必提及它是py3功能。也许我们终于超过了py2->py3的临界点。另外,+1,因为你看起来比被接受的答案提前了1分钟,但该答案使用了相同的函数、可用的名称和所有内容。有@PhilCooper的人谢谢。
#!/usr/bin/env python

def fibonacci():
    a = 0
    b = 1

    def internal_fibonacci():
        nonlocal a, b
        a, b = b, a+b
        return a
    return internal_fibonacci


def main():
    f = fibonacci()
    for i in range(0,10):
        print("f(" + str(i) + ") => " + str(f()))


if __name__ == '__main__':
    main()