Search code examples
pythonscopeglobal-variables

Why are global variables accessible in some functions but not others?


Below is a small section of code that illustrates my question:

index = 0
a = [1, 2, 3, 4]

def b():
    print(index)
    print(a)
def c():
    print(index)
    print(a)
    while a[index] < 3:
        index += 1

b()
c()

I get the following output:

0
[1, 2, 3, 4]
Traceback (most recent call last):
  File "global.py", line 14, in <module>
    c()
  File "global.py", line 8, in c
    print(index)
UnboundLocalError: local variable 'index' referenced before assignment

The function b printed index and a as expected. However, function c neither prints the two variables, nor do they seem to be accessible in the while loop after the print statements.

What is causing the two variables to be accessible in b but not in c?


Solution

  • This line is the difference:

    index += 1
    

    If you set/change a variable anywhere in the function, Python assumes it's a local rather than a global, everywhere in the function. That's the difference between your two functions, b() doesn't try to change it.

    To fix this, you can just out:

    global index
    

    at the top of your c() function, which tells it to assume global no matter what. You may want to do that in b() as well, just to be explicit and consistent.

    Or, you could find a way to do this without globals, which is probably preferable :-) Something like:

    index = 0
    a = [1, 2, 3, 4]
    
    def b(idx, arr):
        print(idx)
        print(arr)
    
    def c(idx, arr):
        print(idx)
        print(arr)
        while arr[idx] < 3:
            idx += 1
        return idx
    
    b(index, a)
    index = c(index, a)