Search code examples
pythonscoping

Yet another python scoping issue


I've read bunch of scoping posts but I haven't found answer to mine. I use python 2.7.6. Here's the code:

def play(A, B):
    state = START_STATE
    #player = None
    while state[1] < goal and state[2] < goal:
        if state[0]:
            player = B
        else:
            player = A
         state = resolve_state(state, player(state))
    return player

This raises UnboundLocalError. Uncommenting line 3 effects in always returning None variable, yet I am sure that the player variable is always either A or B. Making player a global variable solves the problem. Can anyone explain this behaviour? From what I've read while and if statements don't create their scopes so the function should be the scope for variables declared in while/if block.

Error says: "UnboundLocalError: local variable 'player' referenced before assignment"

I am sure that the loop executes because START_STATE = (0, 0, 0, 0) + I double checked it with printing + making player global solves the problem and it doesn't affect the loop entrance conditions

@jonathan -> it stayed from older version


Solution

  • You code is not going through the loop - here's a simplified code that demonstrate it:

    # noloop.py
    
    def loop(A, B, x):
        #player = None
        while x:
            if True:
                player = B
            else:
                player = A
            x = False
    
        return player
    

    and the calls and results:

    >>> import noloop
    >>> noloop.loop("A", "B", True)
    'B'
    >>> noloop.loop("A", "B", False)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "noloop.py", line 12, in loop
        return player
    UnboundLocalError: local variable 'player' referenced before assignment
    >>> 
    

    So your assertions are wrong, point cleared. Note that your code relies on two global variables, START_STATE and goal, which makes debugging harder. First rewrite your function to get rid of all globals (hint : pass START_STATE and goal as arguments), then add some debugging code (like a few print statements before, within and after the loop), and you'll probably find out by yourself what went wrong.