Printing out the fibonacci series

杀马特。学长 韩版系。学妹 提交于 2020-01-21 08:56:50

问题


I am trying to write a simple Python program. It's supposed to return a a closure that returns successive fibonacci numbers:

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())

I get this error at run time: UnboundLocalError: local variable 'n_1' referenced before assignment

EDIT: In my original post, I had not included n = 1 in the definition of fibGen but it was actually a typo. I would still get the same error anyway.


回答1:


Python determines the scope of variables at compile time, based on binding behaviour. If you assign to a name, or use it as an import target (and a few other ways) you are binding the name in a scope.

You are binding to n_1 and n_2 in the fib() function; both are being assigned to. This makes those two names local in fib(), and Python won't even look at the surrounding scope.

You'll need to override this behaviour, and you can do this by using the nonlocal statement:

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 tells the compiler explicitly that you don't want it to look at binding behaviour but instead treat the names as closures.

Next, you are using n in the first branch of the if test, but you haven't defined it anywhere outside of the else branch. You should just return 1 there anyway:

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

Last but not least, you can swap two variables by using tuple assignment, no intermediaries needed:

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



回答2:


You can't modified enclosing variables, n_1, n_2 is in enclosing space not in space of function that's why you can't cahnge the variables.

Use nonlocal keyword

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())


来源:https://stackoverflow.com/questions/26803203/printing-out-the-fibonacci-series

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!