Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Exploring the Local, Enclosing, and Global Scope

00:00 In this lesson, we will explore the first three scopes of the LEGB rule: the local scope, the enclosing scope, and the global scope.

00:11 Let’s start with the local scope. The local scope contains the names that you define inside a function. Every time you call a function, you are also creating a new local scope.

00:22 Let’s play around with the local scope in the IDLE scripting window.

00:29 Here, you’re creating a local variable named total with the value 0 inside of the function print_total(). Inside the function body, you can access total in your print call. Oh, and by the way, in line 3, you’re using a formatted string.

00:44 When you add an = (equal) sign behind the variable name inside the curly braces ({}), then you print out the variable name and the value. Without the = sign, you would only print the value.

00:55 Seeing both the name and the value is handy for us right now because then we don’t have to type the variable total double in the string that we are printing.

01:05 When you run the code, Python calls the function and prints From function: total=0. So the variable total exists in the local scope of print_total(), but outside of print_total(), the variable total does not exist. If you do access the variable outside of the function—so for example, when you add a print() function call here where you show the total variable, or want to show the total variable, and run the code—

01:39 then Python throws an error. And the reason for this is because the print() function in line 6 is not in the same local scope as a variable definition of total.

01:54 The E in LEGB stands for enclosing. The enclosing scope is a special scope that only exists for nested functions. Names that you define in the enclosing scope are commonly known as nonlocal names. Okay, here I adjusted the print_total() function from before to explore the enclosing scope. In Python, you can nest functions.

02:22 These nested functions are also called inner functions. In this example, I added an inner function named inner_print_total() to the print_total() function. I will not go into detail about inner functions, but I’ll give you a link to some Real Python resources if you want to learn more about them at the end of this course. When you run the file, you see that total is 0 both times, and there is no error although you don’t define the variable total inside of inner_print_total().

02:54 This means that a local scope of inner_print_total() can access the enclosing scope, which is the function body of print_total().

03:06 Next up, global scope. The global scope is the top-most scope in a Python program, script, or module. Names are visible from everywhere in your Python code.

03:17 There’s only one global Python scope per program execution.

03:24 Let’s continue with the example from before. This time, the only definition of the total variable is in line 8, where we say total = 5.

03:35 You define the total variable this time in the global scope. That means it’s on the top level of your Python file. Now, top level doesn’t mean it has to be on line 1.

03:46 It means that it isn’t wrapped in a function, for example. To see the global value of total, there’s also a print() function in line 10 ,in addition to the print() functions in lines 3 and 6. When you run the code, then you can see that the global variable total can be accessed from everywhere. There are no errors, and all of our print outputs show the value 5 for the variable total.

04:15 Again, that means all scopes can access the global scope. That’s cool, but it gets better. You can actually define a variable with the same name in every scope.

04:27 So let’s add a variable total in line 3, which is in the inner function named inner_print_total(), and give it the value 7.

04:38 Then let’s move to line 6 and add another variable named total and give it the value 12. Let’s run the code and see what happens.

04:54 So although we have the same variable name, Python doesn’t get confused, because you define the variable total in different scopes. In the inner function, total has the value 7.

05:05 In your print_total() function, total has the value 12. And in your global scope, total has the value of 5.

05:18 Okay, so far we have L, E, and G of the LEGB acronym: the local scope, the enclosing scope, and the global scope. In the next lesson, we will tackle the fourth letter of LEGB and inspect the built-in scope.

Avatar image for ulrichgerhaher

ulrichgerhaher on Feb. 7, 2023

Hi Philipp, you just explained that a variable which is defined in the global scope (so for example at the very beginning of my code) is available in a function. But it seems that this is not the case for functions that are used in threads (using “…concurrent.futures.ThreadPoolExecutor(max_workers=2)…” and “…ex.submit(function)”. Could that be or did I understand something wrong? Regards, Ulrich

Avatar image for ulrichgerhaher

ulrichgerhaher on Feb. 7, 2023

Just found the mistake, now it works ;-)

Avatar image for Philipp Acsany

Philipp Acsany RP Team on Feb. 7, 2023

Hi @ulrichgerhaher, I’m happy you found your mistake. Can you share what it was? 🙂

Become a Member to join the conversation.