Python Closure and Function Decorators

Python is a great programming language , you can write procedural, functional and object oriented code and develop almost anything. While writing code and using some infrastructures, you sometimes need to extend code without touching the original. The object oriented solution for that is inheritance but what if you are writing a procedural code? the answer is function decorator.

Function is an object

One important thing to note about python is that function is an object – you can create functions on the fly, send function to another function and return function from another function. Using the lambda expressions it is also easy to write.

For example, creating a function using lambda expression and send it to another function:



Inner functions

One way to understand that a function is an object is to declare an inner functions and return a function dynamically.

For example, we want to create a fibonacci series, we can do that iteratively or recursively and we want to choose on runtime the method. We can also use an inner function without expose it outside (checkn in this example)

In this example we can use getfib with parameter to decide which implementation we want.



We can return an inner function dynamically and based on the parameters we got on the outer function. For example:

This is useful to generate a function on the fly.  For example if we have set of points (x,y) and we want to use interpolation to calculate y values for points we don’t have:

Now we can use interp1d function to generate a function for us :



Decorator is a function that takes another function as a parameter and extends its behavior without modifying it. This is another good example of closure


Using the @ symbol

You can use the @ symbol as a syntactic sugar to create a decorator:

just remove the function assignment and add the decorator using the @ syntax

You can use any number of decorators you want and even use one more than once:

Nested Decorators

We can call one decorator from another like any other function. For example:

And with the @ syntax :


Decorator With Parameter

While developing frameworks and infrastructures it is very useful so provide features with decorators, for example in Django web framework, we can validate that the user is logged and if not, redirect it to the login page :

Working with decorators is a good pattern when you want to write a function and add functionality that is not related to the implementation like the above example – a view return something only for logged in user

Because a decorator is a function, it can take any parameters you want , so for example, if we want to control the number of header lines in the above example its is easy:

But what about the @ syntax ?

If we try to send the decorator parameter in the “pie” syntax we will get an error:

The problem is that @add_stars(3) is not converted to add_stars(my_function,3). The parameter is ignored

To solve this, we need to do something tricky

We need to convert the parameters to optional arguments and named arguments – to do that we add another helper function:

The function is actually a decorator that returns another decorator with any arguments you want , the returned decorator return a function that will call the original decorator with the optional arguments.

Now we can use that general purpose decorator function to send any parameter we want:






Leave a Reply

Your email address will not be published. Required fields are marked *