Scope of Variables in Python

If you’re familiar with Python or any other programming language, you’ll undoubtedly know that variables need to be defined before they can be used in your program. We’ll start off with variable initialization. Then, we’ll get familiar with the boundary of variables within a program (it’s “scope”). We’ll learn about the four different scopes with the help of examples: Local, Enclosing, Global, & Built-in. These scopes together form the basis for the LEGB rule used by the Python interpreter when working with variables. Finally, we’ll revisit some examples with additional complexity to open the way for the Global Keyword followed by the Non-Local Keyword.

Variable

A variable is a label or a name given to a certain location in memory. This location holds the value you want your program to remember, for use later on. What’s great in Python is that you do not have to explicitly state what the type of variable you want to define is — it can be of any type (string, integer, float, etc.). To create a new variable in Python, you simply use the assignment operator (=, a single equals sign) & assign the desired value to it.

Assigning an initial value to a variable is called initializing the variable. You just initialized the variable: first_string_var with a string value of First String and variable first_int_var with an integer or numeric value of 1.
The part to the left of the assignment operator is the variable name, & the right side is its value. The right-hand side can also be an arithmetic operation - in which case, it will be evaluated before the assignment occurs.

Python has some rules that you must follow when creating a variable:

  • It may only contain letters (uppercase or lowercase), numbers or the underscore character _
  • It may not start with a number
  • It may not be a keyword (you will learn about them later on)

If you don’t follow these rules, you’ll get an error. Try it for yourself.

Variable Scope

Now that we know how to initialize a variable, let’s talk about the scope of these variables. Not all variables can be accessed from anywhere in a program. The part of a program where a variable is accessible is called its scope. There are four major types of variable scope and is the basis for the LEGB rule. LEGB stands for Local -> Enclosing -> Global -> Built-in.

Local Scope

Whenever you define a variable within a function, its scope lies ONLY within the function. It is accessible from the point at which it is defined until the end of the function and exists for as long as the function is executing. Which means its value cannot be changed or even accessed from outside the function. Let’s take a simple example.

We were able to print the first_num variable by calling the function print_number() (# Print statement 1). But when trying to access and then print the same variable from outside the function (# Print statement 2), it raised a NameError. This is because first_num is "local" to the function. Therefore, it can’t be reached from outside the function body.

Enclosing Scope

What if we have a nested function (function defined inside another function)? How does the scope change? Let’s see with the help of another example.

If you got an error that’s because you cannot access second_num from outer() (# Print statement 3). It is not defined within that function. However, you can access first_num from inner() (# Print statement 1), because the scope of first_num is larger, it is within outer().
This is an enclosing scope. Outer's variables have a larger scope and can be accessed from the enclosed function inner().

Global Scope

This is probably the easiest scope to understand. Whenever a variable is defined outside any function, it becomes a global variable, & its scope is anywhere within the program. Which means it can be used by any function.

Built-in Scope

This is the widest scope that exists! All the special reserved keywords fall under this scope. We can call the keywords anywhere within our program without having to define them before use.

Keywords are simply special reserved words. They are kept for specific purposes and cannot be used for any other purpose in the program.
These are the keywords in Python:

LEGB Rule

LEGB (Local -> Enclosing -> Global -> Built-in) is the logic followed by a Python interpreter when it is executing your program.

Let’s say you’re calling print(x) within inner(), which is a function nested in outer(). Then Python will first look if "x" was defined locally within inner(). If not, the variable defined in outer() will be used. This is the enclosing function. If it also wasn't defined there, the Python interpreter will go up another level - to the global scope. Above that, you will only find the built-in scope, which contains special variables reserved for Python itself.

Let’s revisit some examples from before to see if they can create problems when the use-case becomes slightly more complex.

Scenario 1: Global Scope

Remember the greeting_world() function from earlier? Let's say you wanted to be able to change the global variable greeting("Hello") to set a new value ("Hi") for the greeting, so that greeting_world() prints "Hi World".

This didn’t print as planned because when we set the value of greeting to "Hi", it created a new local variable greetingin the scope of change_greeting(). It did not change anything for the global greeting. This is where the global keyword comes in handy.

Global Keyword

With Global, you’re telling Python to use the globally defined variable instead of locally creating one. To use the keyword, simply type “Global”, followed by the variable name. Let’s see this in action on Scenario 1.

That worked! Let’s move onto the next scenario.

Scenario 2: Enclosing Scope

Here, we have a look at the outer() & inner() nested functions from the Enclosing Scope example. Let's try to change the value of first_num from 1 to 0 from within inner().

As you can see it isn’t always that simple. For such purposes, we make use of Non-Local keyword within Python.

Nonlocal Keyword

This is another handy keyword that allows us to work more flexibly and tidily with variable scopes. The Non-Local keyword is useful in nested functions. It 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, & force it to go a level “higher up”. The syntax is similar to the global keyword.

And there you have it!

Conclusion

You now know what Python’s scope of variables is, the LEGB rule, & how you should use the global & Non-Local keywords. You’ll be able to easily manipulate variables in nested functions, without any problem.

RELATED LINKS

Data Scientist & Machine Learning Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store