0

I know about nonlocal keyword and how to fix this error but I am getting a behaviour that I am not understanding in the code below. If you run this, there is no problem

def test( root):
        x=2
        def f2(r):
            print("***")
            x=r #Adding this line is ok
            print("----",x)
        f2(root)
        return x
test(4)

Now try changing x=r to be be the last line in f2 does not work as below

def test( root):
        x=2
        def f2(r):
            print("***")
            print("----",x)
            x=r #Gives an error "local variable 'x' referenced before assignment"
        f2(root)
        return x
test(4)

Thanks

user5908755
  • 51
  • 1
  • 3
  • 1
    The `x`'s are different in the two assigns. When you do `x=r` its a different variable. Check [this](https://stackoverflow.com/questions/39805893/refer-a-global-variable-that-has-same-name-as-the-local-variable-in-python). Also check example 6 [here](https://www.programiz.com/python-programming/global-local-nonlocal-variables). – chriptus13 Jun 18 '20 at 16:33

3 Answers3

0

the problem is in line 5 where you printed x in print("----",x), it doesnt know the x in f2 function so you cant print it

if you want to use that x=2 in f2() you should pass it to it , or using the global key or ...

Ali Rn
  • 1,114
  • 8
  • 19
0

In the first example, you're assigning a new local variable x that is independent of the x in the outer scope. Since you assign this value before you use it, that's fine. The x that you assign 4 to is the one that's local to f2, which is why when you return x from test it's the original 2 value.

In the second example, you do the same thing of assigning a new local variable x (which causes the outer scope's x to be shadowed, same as before), but this time you reference it before you actually do the assignment. That's what generates the error.

If you didn't assign x at all, then it wouldn't be shadowed and you would be able to print its value from the outer scope (meaning you'd see its value as 2, not 4):

>>> def test( root):
...         x=2
...         def f2(r):
...             print("***")
...             print("----",x)
...         f2(root)
...         return x
...
>>> test(4)
***
---- 2
2
Samwise
  • 68,105
  • 3
  • 30
  • 44
0

You have two variables named 'x', in two different scopes. I would not recommend doing this; it can lead to a lot of confusion, leading to bugs in the program.

I would not suggest fixing this with keywords. Rename one of the variables. If you do, the error becomes clear.

def test( root):
        x_test=2
        def f2(r):
            print("***")
            print("----",x_f2)
            x_f2=r 
        f2(root)
        return x_test
test(4)

Clearly, x_f2 is being referenced before assignment. When you write the code like this, the error is clear.

This is exactly what your code is doing; it is just not clear because you have two variables with the same name, in different scopes.

The 'x' inside f2 is a local variable in the function, and you can not use it before assigning it. The fact that in the outer scope there is a different variable named 'x' which has been assigned, does not change that.

Basya
  • 1,477
  • 1
  • 12
  • 22