Découper le code en modules
Objectif : Séparer les fonctions de calcul des dépenses et le point d’entrée du programme dans des modules importables.
Quand le calcul d’un total et le code qui lance le programme sont mélangés, une modification de l’un risque de perturber l’autre. Vous allez séparer ces responsabilités dans le projet de suivi des dépenses : un module portera le calcul métier, tandis qu’un autre constituera le point de départ de l’application.
L’environnement virtuel et la dépendance `requests` sont déjà préparés dans les leçons précédentes ; vous n’avez pas à les modifier ici. Vous allez créer trois fichiers du paquet `depenses` : `__init__.py`, `transactions.py` et `main.py`. Le fichier `requirements.txt` reste inchangé.
1. Distinguer les responsabilités
Un module est un fichier Python contenant du code que d’autres fichiers peuvent importer. Un paquet regroupe des modules dans un répertoire ; ici, `depenses` est le paquet. Le fichier `__init__.py` indique que ce répertoire constitue un paquet Python et permet d’y ajouter plus tard une configuration d’initialisation si le projet en a besoin.
Placez les fonctions qui manipulent les transactions dans `transactions.py`. Gardez dans `main.py` les données de démonstration et l’appel qui lance l’application. Cette séparation permet d’importer le calcul depuis un autre module sans obliger ce module à démarrer toute l’application.
2. Créer le module métier
Dans `transactions.py`, définissez `total_depenses` pour additionner les montants des transactions. Chaque transaction est représentée ici par un dictionnaire avec les clés `date`, `libelle` et `montant`. Cette forme reste simple pour cet exemple ; les prochaines leçons feront évoluer le traitement des données et des erreurs.
"""Fonctions métier liées aux transactions."""
def total_depenses(transactions):
"""Retourne la somme des montants des transactions."""
return sum(transaction["montant"] for transaction in transactions)3. Importer le calcul et définir le lancement
Créez `__init__.py` avec une courte description. Dans `main.py`, utilisez `from .transactions import total_depenses` pour importer précisément la fonction du module voisin. Le point placé devant `transactions` indique un import relatif au paquet `depenses` ; il évite de traiter ce module comme un fichier extérieur au projet.
"""Outils du projet de suivi des dépenses."""Dans `main.py`, placez l’exécution dans une fonction `main`. La condition `if __name__ == "__main__":` appelle cette fonction uniquement lorsque Python exécute ce module comme programme. Si un autre module importe `depenses.main`, le code de lancement ne s’exécute donc pas automatiquement.
"""Point d'entrée de l'application de suivi des dépenses."""
from .transactions import total_depenses
def main():
transactions = [
{"date": "2025-01-15", "libelle": "Courses", "montant": 42.80},
{"date": "2025-01-16", "libelle": "Transport", "montant": 18.50},
]
total = total_depenses(transactions)
print(f"Total des dépenses : {total:.2f} EUR")
if __name__ == "__main__":
main()L’import `from ... import ...` rend l’appel direct : `total_depenses(transactions)`. Vous pouvez aussi importer un module avec `import depenses.transactions`, puis appeler `depenses.transactions.total_depenses(transactions)`. Cette seconde forme rend visible le module d’origine au moment de l’appel ; choisissez une forme cohérente dans le projet.
python -m depenses.mainTotal des dépenses : 61.30 EUR4. Vérifier la structure obtenue
À ce stade, la racine contient toujours `requirements.txt` et l’environnement virtuel `.venv`. Ajoutez le répertoire `depenses` et ses trois fichiers ; les autres fichiers prévus au contrat du projet seront utilisés au fil des leçons. L’organisation obtenue est la suivante :
projet/
├── .venv/
├── requirements.txt
└── depenses/
├── __init__.py
├── main.py
└── transactions.pyVérifiez que la commande affiche bien `61.30 EUR`. Ce résultat correspond à l’addition de `42.80` et `18.50`. Si la commande ne trouve pas le paquet, vérifiez que vous êtes à la racine du projet et que les fichiers sont nommés exactement comme indiqué ; conservez l’indentation de quatre espaces dans les fichiers Python.
À retenir
- Un module est un fichier Python ; le répertoire `depenses` regroupe les modules du paquet.
- Placez le calcul métier dans `transactions.py` et le lancement dans `main.py`.
- Utilisez un import relatif pour relier les modules du paquet.
- La condition `if __name__ == "__main__":` réserve le lancement au module exécuté directement.
- Depuis la racine, lancez le projet avec `python -m depenses.main`.
Dans la prochaine leçon, vous examinerez les erreurs possibles lorsque le calcul des dépenses reçoit des données inattendues.