#! /usr/bin/env python
# -*- coding:Utf8 -*-

"""
Exemples de décorateur.

fichier : decorateurs.py
auteur : Bob
"""

# Import ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import time
from functools import wraps

# Définition de décorateur ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def timer(f):
	"""Prend en paramètre une fonction et retourne un callable."""
	def wrapper(*args, **dargs):
		start = time.time()
		res = f(*args, **dargs)
		print(f"{time.time() - start:.2f} s")
		return res
	return wrapper

def my_decorator(f):
    """Docstring du décorateur."""
    @wraps(f)
    def wrapper(*args, **kwds):
        print('Calling decorated function')
        return f(*args, **kwds)
    return wrapper

# Définition de fonction décorée ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@timer
def sum_poly5(n):
    """Docstring (avant décoration) de sum_poly5()."""
    return sum(x**5 for x in range(n))

@my_decorator
def example():
    """Docstring (avant décoration) de example()."""
    print('Called example function')

# Programme principal =========================================================
## fonction décorée sum_poly5()
sum_poly5(1_000_000)
print(f"Nom : {sum_poly5.__name__}\nDoctring : {sum_poly5.__doc__}")

## fonction décorée example()
print(f"\nNom : {example.__name__}\nDoctring : {example.__doc__}")
