By using decorators, you can add your own processing before or after the processing of existing functions. For example, you had
def decorator(func):
def wrapper(*args, **kwargs):
print('--decorator says hi--')
func(*args, **kwargs)
print('--decorator says bye--')
return wrapper
@decorator
def test():
print('Test function is executed')
test()
This program returns
--decorator says hi--
Test function is executed
--decorator says bye--