# Yunong Cao

#### Some Basic Concepts to Understand Decorators

Functions are objects and they:

• can be assigned to a variable
• can be defined in another function

which means that a function can return another function.

What’s more, if you can return a function, you can pass one as a parameter:

#### Definition

Decorators are:

• “wrappers” - which means that they let you execute code before and after the function they decorate without modifying the function itself
• a pythonic variant of the decorator design pattern

#### Note

• Decorators were introduced in Python 2.4.
• Decorators slow down the function call.
• The order you set the decorators MATTERS.
• You cannot un-decorate a function. (There are hacks to create decorators that can be removed, but nobody uses them.) So once a function is decorated, it’s decorated for all the code.
• Decorators wrap functions, which can make them hard to debug. (This gets better from Python >= 2.5 by having functools module which includes the function functools.wraps() that copies the name, module, and docstring of the decorated function to its wrapper.)

#### Why decorators?

Classic uses are extending a function behavior from an external lib (you can’t modify it), or for debugging (you don’t want to modify it because it’s temporary).

You can use them to extend several functions in a DRY’s way, like so:

Of course the good thing with decorators is that you can use them right away on almost anything without rewriting. DRY, I said:

Python itself provides several decorators: property, staticmethod, etc.

• Django uses decorators to manage caching and view permissions.
• Twisted to fake inlining asynchronous functions calls.

This really is a large playground.

#### Handcrafted Decorators vs Decorator Syntax in Python

Now, you probably want that every time you call a_stand_alone_function, a_stand_alone_function_decorated is called instead. That’s easy, just overwrite a_stand_alone_function with the function returned by my_shiny_new_decorator:

The previous example, using the decorator syntax in Python:

Therefore, @decorator is just a shortcut to:

Of course, you can accumulate decorators:

Using the Python decorator syntax:

The order you set the decorators MATTERS:

Passing arguments to the decorated function

Decorating methods
One nifty thing about Python is that methods and functions are really the same. The only difference is that methods expect that their first argument is a reference to the current object (self).

That means you can build a decorator for methods the same way! Just remember to take self into consideration:

If you’re making general-purpose decorator–one you’ll apply to any function or method, no matter its arguments–then just use *args, **kwargs: