This is a more advanced programming topic, and honestly not one I make much use of myself. However, I got a request to make a lesson on Closures and Decorators. I am going to make it into two lessons to try to make it a bit clearer.
Now to understand closures and decorators, the first thing we need to discuss is nested functions. In programming, nested functions means wrapping a function inside of another function. Here is a very simple example of a nested function:
def outerFunction(x): innerFunction(): print(x) innerFunction()
Now if I just call this with outerFunction(‘Hello World’), the argument x gets passed into the innerFunction which is in turn called by the outerFunction. The result is shown below:
Now why would anyone do this? Outside of just being able to show you that you can? I don’t know. There are reasons for nested functions that involve hiding variables from the code outside of the functions. That is a bit beyond the scope of this lesson. I will try to tackle it when I create my Object Oriented Programming lessons.
For now, let us get on to Closures. Let’s look at the code below:
It is very close to the first example, except notice 2 little changes. First, instead of just calling the innerFunction at the end of the function, we are returning it. Notice there is no () when we return innerFunction
Also notice we are passing the outerFunction to a variable and when we call the var we add () to the end: var()
What we have done now is created an official Closure, let me show you why that matters below.
But, look what happens when I called var(). It is still there. The closure commits the value to memory when you create it. That is not something that would happen from a normal function or even nesting function.
SO WHY THE HELL SHOULD I CARE????
So why this is cool, and why you might use this in the future, is imagine a function that does processer heavy multi-step calculations. If you just keep calling the function as usual, each time you call it, it has to run the whole chain of calculations again. However, once you’ve called it as closure, you don’t have to run the calculations again, you just get the value.
So, how about a more concrete example
Here I created a closure that uses two functions which each take 1 argument, the arguments are then multiplied together.
Notice, I created a variable called double where I sent the outer function mult_by() a value of 2.
When I call double() I can pass it a value for (y)
I can create as many of these instances as I want. Look below, created one for Triple, and notice double is still functional
I’ll continue this in the Decorators lesson.
Just the main thing to keep in mind about closures, is that they improve program performance by no requiring the function to be run each time.
If you are still a little confused after reading this, don’t feel bad. It took me a few tries to finally understand closures myself.