Saturday, July 13, 2013

Using Python decorators for registering callbacks

In my previous post we talked about Python decorators and an intuitive way of remembering how decorators with arguments work.

The following code snippet had triggered the whole chain of thought:

Now that we know what decorators with arguments do, which is essentially - calling the decorator factory with the argument, using the argument to make logical branching in the decorator wrapper and returning the wrapper, we can now try to understand the above code. We first move on to the decorator route's source code found here to see it's implementation. Keep the source code opened in a different tab, as we will refer to it in the later sections.

This code deviates a bit from what we think about how decorators are used - decorators wrap the functionality of a target function with certain pre and post actions, like so:

 Decorator calling func
 In the function
 Decorator called func

But there isn't any call to the target function index in the route function definition. Instead, this code snippet throws light on another functionality of decorators - registering callbacks.

Callbacks are registered functions which are stored in some container data structure (mostly hashes with key as function name and value as function references). For example,

  calling func1 with arg 1
  calling func2 with arg 2

They are useful in building a map of functions and depending on specific user input, the hashes are looked up and the corresponding key's value - which is a function reference is called.

Let us revisit our main snippet. The decorator @app.route('&#47') call leads to:

which in turn leads to the method self.add_url_rule:

  app.add_url_rule('/', 'index', index)

says to Flask - when a user requests for &#47, call the function mapped against the index key, which is the index function.

So that's about it - write a function, declare a decorator above it, that decorator will take the function, store the reference of it in a hash, and will use it whenever an event occurs connected to the key against which the function reference was stored.

Now to paint the whole picture here's a self-contained minimal example of using decorators for registering callbacks:

  This is the main page.
  This is the next page.

Hope you enjoyed going through this post. Do let me know your insights and views in the comments section.


latesttechnologyblogs said...
This comment has been removed by the author.
dan said...

excellent explanation - the best I have seen so far !!!
well done

dk9mbs said...

great explanation. Now I understand the creation of Flask like app classes woth decorator support.