As a python learner, sometimes we see something like @cache
before a function in other’s code in GitHub.
For example1
2
3
4@cache
def function():
###
reutrn output
This @
is called decorator. This article aims to explain what is @
and how useful is this @
Referece: Amo Chen ‘s blog
Understand “why decorator” from example
Let’s say we have three functions to calculate molecular similarity:1
2
3
4
5
6
7
8
9
10
11def similarity1(mol1, mol2):
###
return score1
def similarity2(mol1, mol2):
###
return score2
def similarity3(mol1, mol2):
###
return score3
If we want to know the run time of each function, we may need to edit the function one by one, such as
1 | import time |
when you run the code of these functions, if should give
1 | print (similarity1(mol1, mol2)) # score1, runtime1 |
If we want to insepct the time for more functions, such operation is time-consuming and make the scripts very lengthy.
One for all - decorator
It would be great if there is a function that can be use on top of a function, which add the runtime as an additional ouput of each function. Yes, this is what decorator do: the function of function.
you define a decorator and put the extra operation you want to do in the wrapper function:
1 | def decorator(function): |
When you write1
2
3
4@decorator
def function():
###
return output
it is equivalent to1
function = decorator(function)
Hard to undertand? Let’s write a decorator called timeit to get the time of running a function:1
2
3
4
5
6
7
8
9
10
11
12import functools
import time
def timeit(function):
@functools.wraps(function) # keeps the info of original function
def wrapper(*args, **kwargs):
start_time = time.time()
output = function(*args, **kwargs)
end_time = time.time()
run_time = end_time-start_time
return output, run_time
return wrapper
BTW, args and kwargs are the abbreviations of “arguments” and “keyword arguments”.
and put this decorator in front of each function
1 | @timeit |
Then the output will be exactly same with the previous outputs:
1 | print (similarity1(mol1, mol2)) # score1, runtime1 |
Amazing!