Variable Scopes in Python

Variable Scopes Python Title

Variable scope is an interesting, useful, and easy-to-understand concept that a python programmer must know before dealing with variables and functions. In this tutorial, we will discuss what scopes are, the types of scopes python has, and we will understand the keywords global and nonlocal.

What is a scope?

The scope of a function, class, or any user-defined variable is the region of code in which it can be accessed. A variable declared inside a function can only be accessed in that function, and not outside the function, so that function is the scope of the variable.

For example in the below code:

def funcx():
    x = 1
    print(x)
    return

def funcy():
    y = 2
    print(y)
    return

def funcz():
    z = 3
    print(z)
    return

The variable x is declared in funcx, so funcx is the scope for the variable. Similarly, the scope of y is funcy and the scope of z is funcz.

Understanding Global, Local, and Nonlocal Variable Scopes

In python, there is a variable scope for each variable, i.e. there’s a well-defined boundary in which the variable can be used. Depending on where the variable can be used, the variable can have different types of scopes, let’s talk about them one by one.

1. Global Variable Scope

A variable is said to be in global scope if it can be accessed from anywhere in the python file. See the below code:

x = 10
print(x)
def func():
    print(x)
    return

func()

The variable x is declared outside any function. This means that it can be accessed anywhere in the entire code. In the above example, x is accessed outside the function func as well as inside the func.

The output:

Global: 10
Local: 10

Note: Manipulating a global variable inside a function is a bit more complicated and we will discuss it later with the global keyword.

2. Local Variable Scope

A variable is said to be in local scope if it is declared inside a function. This will make it so that the variable can only be accessed inside that particular function and any attempt to access such a variable outside the function will result in an error if there’s no global variable with the same name.

def func():
    x = 10
    print(x)

In the above function, the variable x is created inside the function, so x is a local variable to func. Attempting to access x outside func will result in an error.

3. Nonlocal Variable Scope

To understand the nonlocal scope, we need to take an example:

def outer_func():
    x = 10
    print("Outside:", x)
    
    def inner_func():
        print("Inside:", x)
        return
    
    inner_func()
    return

outer_func()

In the function outer_func, we have a variable x, so obviously, x is local to outer_func. But to inner_func, x is nonlocal, meaning that x is not local to inner_func but it is not global either.

We can access x from inner_func as a nonlocal variable. And this is the output:

Outside: 10
Inside: 10

Note: Manipulating x from inner_func is a bit more complicated, and we will see that when we discuss the nonlocal keyword.

Manipulating Global and Nonlocal Variables

We have seen that we can access a global and nonlocal variable inside a function, but if we directly attempt to manipulate that variable inside the function, then that will result in an error. Let us see an example:

x = 10
def func():
    x += 1
    print(x)
    return

func()

Now logically, we should be able to increment x as it is a global variable and can be accessed anywhere, but this is the actual output:

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-33-07e029a18d76> in <module>
      5     return
      6 
----> 7 func()

<ipython-input-33-07e029a18d76> in func()
      1 x = 10
      2 def func():
----> 3     x += 1
      4     print(x)
      5     return

UnboundLocalError: local variable 'x' referenced before assignment

It says, UnboundLocalError: local variable 'x' referenced before assignment.

Python is assuming x is local, and telling us to assign a value to it before we can refer it. We know that printing x will work, so this means that such an error occurs if a global variable is directly altered inside a function.

The global keyword in Python

To avoid the discussed error, we can use the global keyword for global variable scopes:

x = 10
def func():
    global x
    x += 1
    print(x)
    return

func()

We can see that we are declaring x as global inside the function and telling Python that x is already declared in the global scope and we will be using that x. The output:

11

So it prints the modified value of x this time.

The nonlocal keyword in Python

For nonlocal variable scopes, we will use the nonlocal keyword to avoid the discussed error as follows:

def outer_func():
    x = 10
    
    def inner_func():
        nonlocal x
        x += 1
        print(x)
    
    inner_func()
    return

outer_func()

We are telling Python that x is nonlocal inside the inner_func function. (global will not work as x isn’t global).

The output:

11

Conclusion

In this tutorial, we discussed what scopes in python mean, we further discussed what global, local, and nonlocal variables are and how to use them. We went through the use of two keywords: global and nonlocal, and we saw them working in python code with their outputs.