打印出斐波那契系列


问题内容

我正在尝试编写一个简单的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: local variable 'n_1' referenced before assignment

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


问题答案:

Python根据 绑定行为 确定编译时变量的范围。如果您分配一个名称,或将其用作import目标(以及其他几种方式),则将名称绑定在范围中。

您绑定到该函数n_1n_2在其中fib();两者都被分配给。这使这两个名称在中成为 本地
名称fib(),Python甚至不会查看周围的范围。

您需要覆盖此行为,并且可以使用以下nonlocal语句来做到这一点:

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
        else:
            n = n_1 + n_2
            n_2 = n_1
            n_1 = n  
            return n
    return fib

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

接下来,您将nif测试的第一个分支中使用,但尚未在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