1

If the following program,test.py is run with python3:

x = 2

def func1():
    x = 3
    print(x)

def func2():
    x = x + 1
    print(x)

func1()
func2()

It generates the following output:

3
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    func2()
  File "test.py", line 8, in func2
    x = x + 1
UnboundLocalError: local variable 'x' referenced before assignment

func1 operates exactly as I would expect. A local variable x is created, assigned the value 3 and printed out.

func2 isn't behaving how I would expect. Based on the expression evaluation order shown here https://docs.python.org/3/reference/expressions.html#evaluation-order

In the following lines, expressions will be evaluated in the arithmetic order of their suffixes:

...

expr3, expr4 = expr1, expr2

I would expect in func2, the statement x = x + 1 would first evaluate the right hand side, obtain the value of x as being 2 from the global scope, evaluate the expression x + 1 to be 3, and assign that value to a local variable x. Finally printing out 3.

Please explain why this isn't how the code is behaving. I have seen other seemingly relevant questions here:

But they simply mention how I should be using the global keyword, they don't really explain the actual evaluation order by Python.

  • This is not a question of evaluation order. Python uses a simple rule: if you assign to a variable name anywhere in a function, then it is considered local to this function, unless declared global. – Thierry Lathuille Oct 10 '21 at 13:49
  • 1
    @ThierryLathuille Thanks for linking to [UnboundLocalError on local variable when reassigned after first use](https://stackoverflow.com/questions/370357/unboundlocalerror-on-local-variable-when-reassigned-after-first-use). [Charlie Martin's answer](https://stackoverflow.com/a/370380/17120019) about the scan being done in two stages, lexing and parsing answers what I was confused about. – HoardingGold Oct 10 '21 at 14:23

0 Answers0