Scope in Python

Kamil Abdurahim

Kamil Abdurahim

0
(0)

The scope or the variable scope in Python is a part of a program where a certain variable is accessible. A variable scope can be categorized as Local, Enclosing, Global, or Built-in.

This article will cover types of variable scope in Python, how they work, and how you can access variables from different scopes.

Local scope in Python

Whenever you define a variable within a function, its scope lies ONLY within the function. This type of scope is known as local scope. Local variables are variables that are declared in a local scope. Local variables are not known to the program outside the scope of the code block they are defined in. Calling a local variable outside its scope in Python generates an error the same as a not declared variable.

Let us take the following program as an example:

def print_num():
    a = 10
    print('Number inside the function:', a)

print_num()
print('Number outside the function:', a)

Running the above program outputs:

Number inside the function: 10
Traceback (most recent call last):
  File "/home/hi/Desktop/local.py", line 6, in <module>
    print('Number outside the function:', a)
NameError: name 'a' is not defined

From the program output above, the print statement in the function outputs the variable’s value while trying to print it causes the program to issue an error. The error NameError: name 'a' is not defined indicates the the variable was either not accessible in the scope it is called in, or the variable is not declared.

Enclosing scope in Python

The scope inside a nesting function (a function that has another function inside it) is an enclosing scope. Local scope exists inside an enclosing scope, and variables declared in the enclosing scope can be accessed in the local scope.

Let us take the following program as an example:

def print_num():
     a = 10
     def print_num2():
         b = 2
         print('print_num2:', a)
         print('print_num2:', b)
     print_num2()
     print('print_num:', b)
 print_num()

Running the program above outputs:

print_num2: 10
print_num2: 2
Traceback (most recent call last):
  File "/home/hi/Desktop/enclosing.py", line 9, in 
    print_num()
  File "/home/hi/Desktop/enclosing.py", line 8, in print_num
    print('print_num:', b)
NameError: name 'b' is not defined

From the previous example, both variables a and b are outputted to the screen from the nested function since variable a is in the enclosing scope and can be accessed from the local scope and b is declared and accessed inside the local scope. The third print statement generates an error because we are trying to access a variable inside an enclosing scope outside its scope and has not been declared outside the nested function.

Global scope in Python

Global scope is a scope outside any function. Variables declared here can be accessed by the whole program. They can be accessed both inside and outside functions.

Let us take another code as an example:

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

The output is as follows:

10
10

The program above outputs the value of x when it is called both in a local scope (in the function) and global scope. This demonstrates that a global variable is accessible anywhere within the code.

Built-in scope in Python

The built-in scope is the widest of them all. The built-in scope is the scope of variables and keywords in the Python language library. Programs can access variables or keywords in this scope without being declared in the program code.

Keywords are special reserved words used by Python. Examples of keywords include: for, while, if, else, and in

LEGB Rule

LEGB rule is the logic that the Python interpreter follows when executing a program. It stands for Local Enclosing Global Built-in, and the order of their execution is respectively.

Let us take consider the program below:

x = 0
def printer():
    x = 1
    def inner_printer():
        x = 2
        print('inner_printer:', x)
    inner_printer()
    print('printer:', x)

printer()
print('global:', x)

When we run the program, the output is as follows:

inner_printer: 2
printer: 1
global: 0

As we can observe, even though the variable is declared differently in all the scopes, Python always checks the for the variable in the current scope the moves up the ladder. The following chart shows how the Python interpreter checks for variables inside a program:

Scope in Python - Scope Inclusion and execution order
Scope Inclusion and execution order

The analogy presented above might sometimes cause problems. Let us take the following scenario as an example:

We want to write a function that modifies a global variable. For example:

h = 'bake bread'
def cake():
    h = 'bake cake'

cake()
print(h)

The program above outputs as follows:

bake bread

Why do u think this happened? There is a simple explanation for this when we set the value of h to ‘bake cake,’ Python created a new local variable named h in the scope of cake(). This does not modify the value of the global variable h. Cases like this are where the global keyword comes in handy.

Global keyword

The global keyword tells Python to use the global variable instead of creating one locally. Using the global keyword, we can now correct Scenario 1 to the way we want it. The following code is the modified version of Scenario 1:

h = 'bake bread'
def cake():
    global h
    h = 'bake cake'

cake()
print(h)

The program above outputs as follows:

bake cake

Now we can finally bake some cake🎂!!!

Nonlocal keyword

Let us consider another scenario:

We want to change the value of a variable in an enclosing scope. For example:

def outer():
    greet = 'Hi'
    def inner():
        greet = 'Bye'
    inner()
    print(greet)

outer()

The program above outputs as follows:

Hi

Cases like this can be corrected using the nonlocal keyword. The nonlocal keyword causes the variable to refer to the previously bound variable in the closest enclosing scope. In other words, it will prevent the variable from trying to bind locally first and force it to go a level ‘higher up’. Its syntax is the same as the global keyword.

The following code corrects Scenario 2:

def outer():
    greet = 'Hi'
    def inner():
        nonlocal greet
        greet = 'Bye'
    inner()
    print(greet)

outer()

The output is as follows:

Bye

Yay, the program can finally say Bye!!!

Summary

This article covered types of variable scope in Python, how they work, and how you can access variables from different scopes. In addition to that, we’ve introduced the LEGB rule, which will help you imaging Python scope boundaries when you’re developing your Python programs.

How useful was this post?

Click on a star to rate it!

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Top rated Udemy Courses to improve you career

Subscribe to our updates

Like this article?

Share on facebook
Share on Facebook
Share on twitter
Share on Twitter
Share on linkedin
Share on Linkdin
Share on pinterest
Share on Pinterest

Want to be an author of another post?

We’re looking for skilled technical authors for our blog!

Leave a comment

If you’d like to ask a question about the code or piece of configuration, feel free to use https://codeshare.io/ or a similar tool as Facebook comments are breaking code formatting.