Python global and nonlocal variable in Python

Most of us are already familiar with global variables in Python. If we declare those variables in a module, the functions inside that module (can read python file or .py file) can access the variable. For example, check the code below :

x = 5

def myfnc():
print(“inside myfnc”, x)
def myfnc2():
print(“inside myfnc2”, x)

myfnc2()

myfnc()

It will print : 
inside myfnc 5
inside myfnc2 5

If you change your code like this :

x = 5

def myfnc():
print(“inside myfnc”, x)
def myfnc2():
print(“inside myfnc2”, x)
x = 10
print(“x = “, x)

myfnc2()

myfnc()

You will get an error :

  File “program.py”, line 6, in myfnc2
    print(“inside myfnc2”, x)
UnboundLocalError: local variable ‘x’ referenced before assignment

The moment you wrote x = 10, Python assume that x is a local variable, and inside the print function, it is giving this error. Because local variables are determined at compile time (from official doc : “local variables are already determined statically”).  You can get rid of the error, if you declare x as global.

x = 5

def myfnc():
print(“inside myfnc”, x)
def myfnc2():
global x
print(“inside myfnc2”, x)
x = 10
print(“x = “, x)

myfnc2()

myfnc()

Now you can run the program again. It won’t throw any error. What if we code like this now?

x = 5

def myfnc():
print(“inside myfnc”, x)
y = 10
def myfnc2():
global x
print(“inside myfnc2”, x, y)
x = 10
print(“x = “, x)

myfnc2()

myfnc()

If you run the program, you will see desired output. But now, if you want to write to y inside myfnc2() (for example, assign something like y = 1), you can’t use global y, as y is not a global variable. You can try this following code that fails successfully :

x = 5

def myfnc():
print(“inside myfnc”, x)
y = 10
def myfnc2():
global x
global y
print(“inside myfnc2”, x, y)
x = 10
print(“x = “, x)
y = 1
print(“y = “, y)

myfnc2()

myfnc()

You will get this error : NameError: name ‘y’ is not defined
We need to understand that, y is not a global variable. Here nonlocal can help! Instead of global y, just write nonlocal. It will make y available and writable inside myfnc2(). 
x = 5

def myfnc():
print(“inside myfnc”, x)
y = 10
def myfnc2():
global x
nonlocal y
print(“inside myfnc2”, x, y)
x = 10
print(“x = “, x)
y = 1
print(“y = “, y)

myfnc2()

myfnc()
This is something I learnt today. :)


life is short – you need Python!