[[Python]] https://realpython.com/primer-on-python-decorators/ ```python from datetime import datetime def not_during_the_night(func): def wrapper(): if 7 <= datetime.now().hour < 22: func() else: pass # Hush, the neighbors are asleep return wrapper def say_whee(): print("Whee!") say_whee = not_during_the_night(say_whee) ``` is equivalent to ```python def my_decorator(func): def wrapper(): print("Something is happening before the function is called.") func() print("Something is happening after the function is called.") return wrapper @my_decorator def say_whee(): print("Whee!") ``` Boilerplate template: ```python import functools def decorator(func): @functools.wraps(func) def wrapper_decorator(*args, **kwargs): # Do something before value = func(*args, **kwargs) # Do something after return value return wrapper_decorator ``` Practical use cases - adding a timer or debug wrapper to a function Built in decorators: - `@classmethod` [[@classmethod]] - `@staticmethod`