Search code examples
python-3.xlocal-variablesnested-function

how local variables work inside nest function in python 3?


I have the code:

def main(m):
    res = m
    def help(a, b):
        print(res)
        #res = min(res, a*b)
    help(3,2)
    return res
main(3)

The code works. However

def main(m):
    res = m
    def help(a, b):
        print(res)
        res = min(res, a*b)
    help(3,2)
    return res
main(3)

it raise UnboundLocalError: local variable 'res' referenced before assignment

def main(m):
    global res
    res = m
    def help(a, b):
        print(res)
        res = min(res, a*b)
    help(3,2)
    return res
main(3)

It seems that I add global res does not change. what happens here? How to update res inside the function help?


Solution

  • You need to tell the inner function that the res variable is nonlocal, like this:

    def main(m):
        res = m
        def help(a, b):
            nonlocal res
            print(res)
            res = min(res, a*b)
        help(3,2)
        return res
    main(3)
    

    You can read from a non locally scoped variable without issue in a function, but if you try to write to a variable then python assumes that you want to create a new locally scoped variable. That local variable hides and prevents access to any similarly named variable that may exist in the namespace of higher scopes, like outer functions or global variables. To inform it that you do not want to create a local variable and want to access the outer scope variable you need to use the nonlocal keyword as in the above example.

    Using global res does not fix it because global variables are at the top level of the namespace hierarchy and the res variable that you are trying to access is not. The res you want to access is in between the global scope and the local scope. That is why you need to use nonlocal instead of global. If res were at the top/external level then global would have been the solution.