Les modules et les packages
Introduction
En Python, les modules et les packages permettent d’organiser le code, de séparer les responsabilités et de réutiliser des fonctionnalités. Un module correspond à un fichier dont l'extension est .py, contenant des définitions, telles que des fonctions et des classes, ainsi que des instructions. Un package regroupe des modules et, éventuellement d’autres packages, dans une structure hiérarchique.
Les modules
Créer un module
Un module implémenté en Python correspond à un fichier dont l’extension est .py, contenant des fonctions, des classes, et des instructions.
Créons un fichier nommé pricing.py :
DEFAULT_TAX_RATE = 0.20
def calculate_total(price: float, tax_rate: float = DEFAULT_TAX_RATE) -> float:
return price * (1 + tax_rate)
Le nom du module est pricing, sans l’extension .py.
Importer un module
Dans un fichier main.py, placé dans le même dossier, nous pouvons importer ce module avec le mot-clé import :
import pricing
total = pricing.calculate_total(100)
print(total) # 120.0
print(pricing.DEFAULT_TAX_RATE) # 0.2
Pour accéder aux éléments du module, nous préfixons leur nom par celui du module, suivi d’un point.
Importer un élément
Les mots-clés from ... import ... permettent d’utiliser directement un élément du module :
Il est également possible d’importer plusieurs éléments :
Définir un alias
Le mot-clé as permet d’attribuer un alias au module ou à l’élément importé :
Un alias peut aussi être appliqué à une fonction :
Il est conseillé d’éviter les imports avec *, car ils rendent plus difficile l’identification du module dont provient chaque nom et peuvent créer des conflits de noms.
Exécuter un module comme un script
Un fichier Python peut être importé ou exécuté. La variable __name__ permet de distinguer ces deux situations. Complétons le fichier pricing.py :
DEFAULT_TAX_RATE = 0.20
def calculate_total(price: float, tax_rate: float = DEFAULT_TAX_RATE) -> float:
return price * (1 + tax_rate)
if __name__ == "__main__":
print(calculate_total(100))
Lorsque nous exécutons ce fichier :
Si la variable __name__ vaut "__main__" alors l’instruction print est exécutée. Lorsque nous importons le module, cette variable vaut "pricing"et cette instruction n’est pas exécutée.
Le code placé en dehors de ce bloc est exécuté lors du premier import du module dans le processus. Les traitements exécutés doivent donc être placés dans ce bloc.
Les packages
Créer un package
Un package permet de regrouper des modules et, éventuellement, des sous-packages. Créons les fichiers suivants :
| Chemin | Rôle |
|---|---|
main.py |
Point d’entrée de l’application |
shop/__init__.py |
Initialisation du package shop |
shop/pricing.py |
Calcul des prix |
shop/product.py |
Gestion des produits |
Dans un package classique, le fichier __init__.py identifie le dossier qui le contient comme un package. Il peut rester vide ou contenir du code d’initialisation.
Python permet de créer des packages d’espace de noms sans qu'un fichier __init__.py soit présent, notamment pour répartir un package entre plusieurs emplacements.
Importer un module du package
Depuis main.py, nous pouvons importer le module pricing :
Nous pouvons aussi importer directement la fonction :
Les points séparent les niveaux de la hiérarchie : shop désigne le package et pricing son module.
Définir des sous-packages
Un package peut contenir d’autres packages. Par exemple, les fichiers suivants définissent un sous-package nommé services :
| Chemin | Rôle |
|---|---|
shop/services/__init__.py |
Initialisation du sous-package |
shop/services/order_service.py |
Gestion des commandes |
Une classe définie dans order_service.py peut être importée de cette manière :
Les imports absolus et relatifs
Un import absolu indique le chemin depuis le package de premier niveau :
Un import relatif indique le chemin depuis le package auquel appartient le module courant.
Par exemple, dans shop/product.py, importons une fonction de l'autre module :
Le point désigne le package courant. Deux points permettent de remonter d’un niveau :
Les imports relatifs nécessitent que Python connaisse le package auquel appartient le module. Pour exécuter un module du package comme un script, nous pouvons utiliser l’option -m depuis le dossier contenant shop :
Utiliser la bibliothèque standard
Python fournit une bibliothèque standard regroupant de nombreuses fonctionnalités. Par exemple, le module math propose des fonctions mathématiques :
D’autres modules sont disponibles, notamment json pour manipuler des documents JSON, datetime pour travailler avec les dates et heures et pathlib pour manipuler les chemins et effectuer des opérations sur les fichiers et les dossiers.
Quelques repères pour les développeurs C#
| Python | Repère en C# |
|---|---|
| Module | Code possédant son propre espace de noms |
| Package | Organisation hiérarchique des modules, comparable dans son usage à une organisation par namespaces. Un package Python ne correspond pas à un assembly .NET ou à un package NuGet. |
import |
Rend un module accessible et peut exécuter son code permettant de l'initialiser |
from ... import ... |
Importe des noms précis d’un module, utilisables sans les préfixer par le nom du module |
if __name__ == "__main__": |
Exécute un bloc lorsque le module est utilisé comme point d’entrée, notamment avec python fichier.py ou python -m package.module. |