Motivation
Python decorators are a nice way to implement the decorator pattern. Perhaps you read the article about Python data classes
and wondered how the @dataclass thingy worked.
Example
Let’s say we created the following function:
def un_decorated_function():
print('--> Starting un_decorated_function')
print('Inside un_decorated_function')
print('<-- un_decorated_function finished')
This works but violates the DRY principle if repeated for every function we write.
We can use a decorator to log entry and exit of a function like this:
from functools import wraps
def logging():
def wrapper(f):
@wraps(f)
def wrapped(*args, **kwargs):
print('--> Starting ' + f.__name__)
ret_val = f(*args, **kwargs)
print('<-- ' + f.__name__ + ' finished')
return ret_val
return wrapped
return wrapper
The syntax is a bit quirky at the beginning. But if you stick to this template you can adapt the decorator to your needs.
@logging()
def my_function():
print('Inside my_function')
@logging()
def my_other_function():
print('Inside another_function')
if __name__ == '__main__':
my_function()
my_other_function()
And get the output:
--> Starting my_function
Inside my_function
<-- my_function finished
--> Starting my_other_function
Inside another_function
<-- my_other_function finished