1

I was wondering if someone could explain this behavior to me

x = 10
def foo1():
   y = x + 1
   print(y)  #This works, because x exists

def foo2():
   y = x + 1  #This line throws an exception even if the value exists
   print(y)
   x = y

This throws a UnboundLocalError: local variable 'x' referenced before assignment. I understand that I could declare x as global at the beginning of foo, but I'm curious where in the language this is defined. I would expect that the first line would read the global x and the second line would write the local x. Why is this not the case?

Tim
  • 361
  • 1
  • 5
  • 14
  • 3
    This is defined in https://docs.python.org/3/reference/executionmodel.html. Answer that extracts the relevant bits: [Global variable changed by multiple functions - how to declare in Python](http://stackoverflow.com/a/23998923) – Martijn Pieters Jul 01 '14 at 21:55
  • 1
    `x` is local because it is assigned to somewhere in the function. Python won't use the global variable of the same name just because the local hasn't been assigned a value yet. – kindall Jul 01 '14 at 21:56
  • Also related: [Why does assigning to my global variables not work in Python?](http://stackoverflow.com/q/929777), [Unbound variable and name](http://stackoverflow.com/q/22101836) – Martijn Pieters Jul 01 '14 at 21:58
  • @MartijnPieters I think the answer is in your first comment, but I don't think this is an exact duplicate. I edited my question to be a little clearer. – Tim Jul 01 '14 at 22:10
  • But why would the second value write anything to `x`? It is a local name, not a global. Scope applies to the whole block, not global first then local later. – Martijn Pieters Jul 01 '14 at 23:07
  • In my example foo1 and foo2 are identical until foo2 tries to set x. It's surprising to me that code which has not yet executed implicitly changes the meaning of earlier code, I.e. turns a global read only into a local – Tim Jul 01 '14 at 23:11
  • That's why I explain that it is not decided at runtime. It is decided at *compile time*. It is the block that determines the scope. If it is local *somwhere* in the function, it is local *everywhere* in that function. – Martijn Pieters Jul 02 '14 at 08:11

0 Answers0