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

Unlock This Lesson

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

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Using Functions as Return Values: Closures

For more information on topics covered in this lesson, check out these resources:

00:00 In this lesson, we’ll explore how and why you might use a function as a return value. In Python, functions are considered first-class objects. This means they can be assigned to a variable, used as an argument to a function, or used as the return value of a function. Here, specifically, this means that we can use a function object as the return value in any return statement. A function that returns a function or takes a function as a parameter is referred to as a higher-order function.

00:35 A closure factory function is an example of a higher-order function. This type of function takes an argument and returns an inner function. This inner function is usually known as a closure.

00:52 A closure carries information about its enclosing execution scope. This provides a way for a function to keep track of its state information between function calls. Closure factory functions are useful when you need to write code based on the concept of lazy or delayed evaluation. As an example, suppose you want to write a function that takes a single number and provides the result of multiplying that number by a specific factor.

01:23 Say you always want to multiply a number by 2, or another function that always multiplies a number by 7, and so on. In this context, the value of the factor is going to be the same for a series of runs of this function. Here is a simple example, but it takes two arguments and doesn’t take into account that one of them, factor, isn’t going to change much. Let’s do a little bit better.

01:51 This other function uses a closure to retain the value of factor between function calls. Inside by_factor() is an inner function called multiply(), which is created and returned without being called.

02:09 The function object returned is a closure that retains information about the factor being used. When you give a value for factor, by_factor() returns a function that knows to multiply its only parameter number by the factor provided as an argument when by_factor() was called.

02:35 Here are a couple of examples of how we might use it.

02:41 We’re going to create a function called double(), which uses by_factor() to give us a function which always multiplies by 2.

02:53 So by_factor() returned for us a function that’s going to multiply a single parameter by 2. When we call double() with an argument, it essentially calls multiply() using 2 for factor and whatever number was provided for the parameter number.

03:18 Similarly, we can create a function triple(),

03:25 which always uses 3 for the factor in multiply().

03:31 So if I triple 3, I get 9, and if I triple 4, I get 12. double() remembers that factor was 2 and triple() remembers that factor was 3.

03:47 You can also use lambdas to create closures. This often provides a more concise version of your closure factory. For example, we just returned the lambda which takes the number and multiplies it by the argument provided in factor when by_factor() creates the function.

04:07 So by_factor() takes a factor and it returns for us a function defined as a lambda, which takes a number and multiplies that number by the factor provided when this lambda is created.

04:26 Again, I can create a double() method, which calls by_factor() with the argument of 2, and it returns a function that takes a number and multiplies and returns that number multiplied by this factor 2 we’re providing it.

04:43 So again, double(3) gives us 6, double(4) gives us 8, and we could define triple() and observe the same results we did before.

04:56 For more information about inner functions, generators, lambdas, and anything else from this lesson, please check out the links below the video. Next, we’ll look at using decorators to write functions that take and return functions.

Become a Member to join the conversation.