Posts in decorators

Python: Intro to Decorators

Do you even decorate, bro? – Intro to decorators

When looking at the Python programming language, some of the most powerful and, unfortunately very under utilized “macro” design pattern within the language. One of the reasons I believe this to be the case is that most explanations of decorators suck. When you read the word “decorator” in regards to application development, most people generally think of http://www.amazon.com/gp/product/0201633612/ref=ase_bruceeckelA/ . While the “decorator” in Python can indeed be implemented in this fashion of design pattern, it is a very limited version of what decorators can actually accomplish.

I believe that decorators can actually be thought of as more “macros”, than the classical design pattern aforementioned above. http://en.wikipedia.org/wiki/Macro_(computer_science) , as defined by Wikipedia is “a rule or pattern that specifies how a certain input sequence (often a sequence of characters) should be mapped to a replacement output sequence (also often a sequence of characters) according to a defined procedure.” In short, if you have some metadata that you want to apply to any class, function or object, dress it up with a decorator.

Enough already, get to the example!

Decorators allow you to inject or modify code in functions or classes. Sounds a bit like Aspect-Oriented Programming (AOP) in Java, doesn’t it? So lets say you have an action that you would like to perform at the entry point (execution) or exit point (return) of a class, function. This is a prime example as when to use a decorator.

```python decorator example.py

@myDecorator def myFunction1():

 print (‘hello from inside myFunction1()’)

```

note the

```python myscript

@myDecorator # The @myDecorator denotes the the application of a decorator

```

Function decorators

So by affixing a @decoratorname on a line directly above a function (or object), denotes the application of the results of a decorator function. In the previous example, when the python parser passes over the “myFunction()”, “myFunction()” is compiled and is, in turn, passed to the “myDecorator code block. This code block creates a function-like object that is ultimately what is returned when calling the “myFunction()” function. Confusing? Maybe this example will help.

```python decorator_example2.py

class myDecorator(object):

def __init__(self, func_object):
    print ("Hello from inside myDecorator.__init__()")
    func_object() # Execute func_object() to prove it has been executed.
def __call__(self):
    print ("Hello from inside myDecorator.__call__()")

@myDecorator def myFunction():

print ("Hello from inside myFunction()")

print (“Finished decorating myFunction()”) myFunction()

```

When you execute the above code, your results will look something like this:

```text output

Hello from inside myDecorator.init() Hello from inside myFunction() Finished decorating myFunction() Hello from inside myDecorator.call()

```

Note that the initialization of myDecorator(object) is executed when myFunction() is called. Due to the fact that we call “func_object()”, which is just myFunction() passed into the decorator class.init as a function object labeled “func_object”. Generally, you’ll pass the function object in the constructor and later use it in the call() method.

When myFunction() is called after it has been decorated, we get completely different behavior; the myDecorator.call() method is called instead of the original code. This is due to the fact that decoration replaces the original function object with the result of the decoration. In our case, the myDecorator object replaces myFunction.

This is it for the introduction to Python decorators, however look out for part II, coming soon… ☺

written in Python, decorators, design patterns