After stripping the special sparkle off your functions, you'll now revisit scopes to keep building on the foundations for understanding decorators.
Revisit Previous Scope Lesson
Feel free to revisit the lesson on scopes from earlier in the course. In this lesson, you'll look at it from the perspective of a weird function:
def outer_func():
msg = "Weeeeeekend!"
def inner_func():
print(msg)
return inner_func
Looks weird? Well, here you have a function definition that itself defines a function and then returns that inner function. That sounds like boxes inside of boxes, doesn't it? Time for you to experiment with this code to better understand what this structure does.
Experiment with Scope
Make sure to copy the code snippet and try running these experiments in your own IDE. What happens when you call outer_func():
outer_func()
Hm... Nothing?
Photo by Cristina Lavaggi https://unsplash.com/@cristinalavaggi
Is this what you expected? Time to take a step back and reconsider the code snippet.
What did outer_func() return? It returned the function object inner_func. That is one of those plain old function objects that you read about in the previous lesson. You already know that you can assign a function object to a variable:
say_wee = outer_func()
With this line of code, you're assigning the return value of outer_func() to the variable say_wee. The return value is the function object inner_func.
After doing this, you can call say_wee. It is, after all, just a reference to a function object:
say_wee()
# OUTPUT: Weeeeeekend!
And when you call say_wee(), you'll see that it dutifully prints the message that you defined as msg inside of outer_func().
Wait a moment! You're calling inner_func() via the variable say_wee, but msg was defined inside of outer_func() instead! How is it possible that it still prints out that message? Now, you're at the point where you'll need to understand scopes.
Understand the Python Scope
Despite the fact that msg is assigned inside of outer_func(), it also lives inside of the inner scope of inner_func(). You might already have expected that, but a little training is always better:
Tasks
- Revisit the exercise about scopes in Python.
- Write an example where you use a variable defined in an outer scope in an inner scope.
- Overwrite a variable name from an outer scope in an inner scope and confirm that it has been replaced.
Once you did a proper revisit of scopes in Python, the outcomes of the experiment you did before shouldn't be a surprise anymore:
def outer_func():
msg = "Weeeeeekend!"
def inner_func():
print(msg)
return inner_func
say_wee = outer_func()
say_wee()
# OUTPUT: Weeeeeekend!
Make sure you understand why you're able to use the msg variable in inner_func() before moving on.
In the next lesson, you'll learn how you can pass arguments in a function instead of hard-coding them as you did with msg in this lesson.
Additional Resources
- Real Python: Inner Functions: What Are They Good For?
- Real Python: Python Scope & the LEGB Rule: Resolving Names in Your Code
Summary: Understand the Scope
- Everything from a more outer scope will be available in an inner scope
- Not everything in an inner scope is available in an outer scope
- If you define a variable with the same name in a more inner scope, it will overwrite the variable from the outer scope