0

The following code was more unpredictable than I had expected.

Test case 1:

# Line with print is OK:

y4 = 0    

def G6():
    print(f"y4={y4}")

G6()

Output: y4=0

Test case 2:

# Line with print throws error this time:
# UnboundLocalError: local variable 'y5' referenced before assignment
# But why exactly? If y5 is a local variable, then y4 (above) should be too, IMO.
# Is y4 (above) even a local variable? Is y4 (above) also being referenced before assignment, or not?

y5 = 0    

def G7():
    print(f"y5={y5}")
    y5 += 2

G7()

Output on the line print(): UnboundLocalError: local variable 'y5' referenced before assignment

Can this python behavior be rationalized?

Geoffrey Anderson
  • 1,534
  • 17
  • 25
  • 1
    Names are local **when bound to in a function**. So `y5` is local because you assigned to it, and assignment is a binding action. See [*Naming and Binding*](https://docs.python.org/3/reference/executionmodel.html#naming-and-binding) – Martijn Pieters Jul 06 '19 at 12:16
  • Also see the duplicate, the top answer defines local as: *L, Local — Names assigned in any way within a function (def or lambda)), and not declared global in that function.* – Martijn Pieters Jul 06 '19 at 12:19
  • Why does line with print throw error, but not line with the reading of y5? This is the gist of my question. – Geoffrey Anderson Jul 06 '19 at 13:09
  • Because `y5` is a local variable in `G7`, and you can't use one variable both as a local and a global in the same scope. Python determines the scope *at compile time*, not at runtime, `y5` is a local variable because you assign to it with `y5 += 2`, making **all** references to `y5` inside `G7` a local variable. When you try to print `y5` nothing has been assigned to it yet. – Martijn Pieters Jul 06 '19 at 13:56
  • Thank you. Now notice that 0 was assigned to y5 as the first line of code. Why can't the function read y5? – Geoffrey Anderson Jul 06 '19 at 14:26
  • Because it is *not the same variable*. `y5` is assigned to in the global scope so it is a global. Variables have scope and a name, for you to access a given variable you need to match both. If you want `y5` inside a function to be seen as a global, *and* you want to bind to it, you must tell the Python compiler so explicitly with `global y5`. – Martijn Pieters Jul 06 '19 at 15:43

0 Answers0