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.
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.
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.
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.
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
outer() (# Print statement 3). It is not defined within that function. However, you can access
inner() (# Print statement 1), because the scope of
first_num is larger, it is within
This is an enclosing scope.
Outer's variables have a larger scope and can be accessed from the enclosed function
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.
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 (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
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
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.
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
inner() nested functions from the Enclosing Scope example. Let's try to change the value of
first_num from 1 to 0 from within
As you can see it isn’t always that simple. For such purposes, we make use of Non-Local keyword within Python.
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!
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.
Python Scope & the LEGB Rule: Resolving Names in Your Code - Real Python
In this step-by-step tutorial, you'll learn what scopes are, how they work, and how to use them effectively to avoid…