How to write python decorators
What are decorators
Decorators are special types of function in python that was introduced in PEP-318. It is a function that extends or change the behavior of a function/class.
Basic decorator syntax
A decorator can be defined as any other python functions. It needs to accept a function as in input and return another function as output.
The @
symbol applies the decorator on the function it annotates.
When you execute print_name
, it will execute the wrapped version.
Experimenting with the decorator ‘@’ syntax
What if you want to accept some arguments to construct the decorator? Let’s say
you want to alter scream_when_invoked
to scream a different value.
The awesome thing about @
is that it just expects a function that takes a
function and returns a function. And any statement after @
is evaluated
before the decorator is applied.
This will print the expected result with the custom line
being screamed
But what other things will @
accept?
It will accept variables
It will accept callable objects
In fact it supports any named expressions
The decorator symbol ‘@’ can be followed by
any named expressions
that evaluates to (func) -> func
.
decorators: (‘@’ named_expression NEWLINE )+
Here’s an extreme example where even an next
expression can be used.
Decorating functions with arguments
We used the example print_name
as the function being decorated. But what if
you need to decorate a function that accepts arguments?
You can either make it generic or specific to the type of function you decorate.
Specific params
Let’s say you only need to decorate functions that accepts lists and returns lists. Your decorator can focus on handling functions that accepts lists only
append_777
will append 777 to any list returned by the function it decorates.
Generic params
You can also accept all functions by using generic parameters.
scream_before_and_after
will print before and after it executes the function.
Decorating classes
Decorators can decorate classes as well. It will accept a class and must return a class. The wrapper class can even extend the decorated class.
add_last_name
adds the last name Nye
to any classes that contains a name
field. In our case, the Person
class was modified.
Awesome Decorator Usages
Decorators are commonly used for things like timers and declaring @staticmethod for a class, I’ve collected some examples of crazy uses you can push decorator to do.
-
Patching the function code and implementing goto
This is one of the greatest
decorator
usage I’ve seen. The author wrote a decorator that will modify the code of the function passed in and makegoto
andlabel
work in python -
Timeout decorator that limits the execution time of function
There is so much utility in being able to manage the execution time of a function. Having this as a decorator makes implementing timeout behavior with functions a lot easier.
-
Rate limiting how many times a function can be called
This is another decorator that makes multi-threaded python easier. You can wrap any functions and specify how many times it can be called per time period.