1

This question stems from curiosity rather than a need to solve some particular problem. Given the two snippets of code below, why does the first produce an unbounded local error while the second does not? They appear to have the same critical sequence of operations in my mind, but there must be some under-the-hood magic at work that I am missing.

    x=5

    def fun1():
      x=x+2                # or x+=2
      print x

    def fun2():
      z=x+2                
      print z

I understand that to make the first function work, the global function must be passed. I just want to know what the interpreter does to make those two statements much more different than they seem. Thanks.

  • This question is different from similar questions in that it asks for the underlying cause of this behavior and not a solution for mitigating it.
Bach
  • 6,145
  • 7
  • 36
  • 61
smoles
  • 67
  • 1
  • 4
  • 1
    http://stackoverflow.com/questions/423379/using-global-variables-in-a-function-other-than-the-one-that-created-them – karthikr Feb 21 '14 at 03:51
  • Because that's how it works. You can reference a global variable in a function all you want, but you can't assign to it without marking it as `global`. – BrenBarn Feb 21 '14 at 03:51
  • This question asks why this occurs not what to do about mitigating the issue. That is a different question all together. – smoles Feb 21 '14 at 05:58

1 Answers1

2

There's actually a good/bad reason for this, and it's because you used specifically x=x+2.

Take these three functions as an example:

x = 5

def f1(): # Executes with no error
    x = 5

def f2(): # Unbounded local error
    x = x + 5

def f3(): # Executes with no error
    y = x + 5

This happens because when you execute x = 10, or any statement with x being assigned, Python uses the local version of x in the statement. Assigning x = 10 is thus fine. You are simply setting the local version of x to 10.

However, when you try x = x + 5, or x += 5 (which is the same thing), then Python uses the local version of x for the right hand side x as well, because you are also assigning the local version on the left hand side. But it hasn't been created yet! Which is why you get the error.

The issue is that when you assign to a variable name, Python assumes any references to that name in the right hand side of the assignment are in the same scope.

In the function f1, Python assigns 5 to the local variable x, with no problems.

In the function f2, Python creates the variable x, and tries to assign x + 5 to it, using the same local x as was just created. And since x doesn't exist yet, it can't read from its value, and throws an error.

In the function f3, since you are not assigning a value to x, Python chooses the global version of x, and reads from its value.

There is probably someone who can explain the internal workings of this better than me.

icedtrees
  • 6,134
  • 5
  • 25
  • 35
  • I'll take it. I did not think that the interpreter could create and call a variable in the same line of code... Thank you! – smoles Feb 21 '14 at 05:54