1

Given the following code:

U = [1,2,3]

def test():
    # global U
    u = U * 2
    print(u)
    # U = u

test()
print(U)

In this form prints(u) displays [1,2,3,1,2,3]. This means 'U' was read successfully in the function.

But if I uncomment the U = u line then I receive the following error message:

 u = U * 2 UnboundLocalError: local variable 'U' referenced before assignment

which I can only fix by uncommenting the 'global U' line. I dont understand this though. Previously u=U*2 worked just fine. Why is an error raised at u=U*2 if I uncomment a line below it?

EDIT: I dont think it is duplicate. My question is why do I see an error in a line which is unmodified. In my real code there are about 100 lines between 'u=U*2' and 'U=u' and it took me couple hours ro realize that the error is actually somehow caused by the 'U=u' line.

Istvanb
  • 392
  • 2
  • 6
  • 19
  • Also https://stackoverflow.com/questions/9264763/unboundlocalerror-in-python – cs95 Oct 30 '17 at 11:16
  • The line `global U` will fix your problem. It is fine that you found a minimal example of your bug. I can confirm that your problem is a duplicate of these or if you understand them you will also understand your problem. – hynekcer Oct 30 '17 at 13:51

1 Answers1

1

U = ... creates a local variable U. It doesn't matter where in the function this appears, at the beginning or the end, Python is resolving all those things when it parses the function body. It doesn't matter that there's a global variable U as well in this case, it is being shadowed by the local variable U appearing in the function body. So the problem boils down to you trying to do U * 2 before you have defined U. You could call the variable anything else besides U for the same effect.

To clarify:

u = U * 2
U = u

This does not mean read the global U, then create a local U. By U = ... appearing anywhere inside the function body, Python reserves the name U as a local variable name. The same name cannot ambiguously refer to a global variable and in the next line to a local variable.

When you also add global U, you're clarifying for Python that the name U in the local function scope refers to the global variable U always.

When you omit U = ..., then there's no local variable of that name being created anywhere inside the function, and Python looks up the value of U from the surrounding scope when getting its value.

deceze
  • 510,633
  • 85
  • 743
  • 889