Fix Python – Python nested functions variable scoping [duplicate]

Question

Asked By – Stefan Manastirliu

I’ve read almost all the other questions about the topic, but my code still doesn’t work.

I think I’m missing something about python variable scope.

Here is my code:

PRICE_RANGES = {
                64:(25, 0.35),
                32:(13, 0.40),
                16:(7, 0.45),
                8:(4, 0.5)
                }

def get_order_total(quantity):
    global PRICE_RANGES
    _total = 0
    _i = PRICE_RANGES.iterkeys()
    def recurse(_i):
        try:
            key = _i.next()
            if quantity % key != quantity:
                _total += PRICE_RANGES[key][0]
            return recurse(_i) 
        except StopIteration:
            return (key, quantity % key)

    res = recurse(_i)

And I get

“global name ‘_total’ is not defined”

I know the problem is on the _total assignment, but I can’t understand why.
Shouldn’t recurse() have access to the parent function’s variables?

Can someone explain to me what I’m missing about python variable scope?

Now we will see solution for issue: Python nested functions variable scoping [duplicate]


Answer

When I run your code I get this error:

UnboundLocalError: local variable '_total' referenced before assignment

This problem is caused by this line:

_total += PRICE_RANGES[key][0]

The documentation about Scopes and Namespaces says this:

A special quirk of Python is that – if no global statement is in effect – assignments to names always go into the innermost scope. Assignments do not copy data — they just bind names to objects.

So since the line is effectively saying:

_total = _total + PRICE_RANGES[key][0]

it creates _total in the namespace of recurse(). Since _total is then new and unassigned you can’t use it in the addition.

This question is answered By – David Webb

This answer is collected from stackoverflow and reviewed by FixPython community admins, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0