Lors du développement en Python, une situation courante consiste à avoir pluseiurs fichiers Python qui doivent interagir. Une approche simple pour de petits projets est de copier les fichiers nécessaires dans le répertoire courant avant de les importer. Cependant, cette méthode devient rapidement inefficace lorsque la complexité du projet augmente.
Une solution élégante pour organiser plusieurs fichiers Python et faciliter leurs appels mutuels consiste à utiliser les packages Python, où le fichier init.py joue un rôle crucial.
Comprendre le processus d'importation en Python Lorsque Python exécute une instruction d'importation, il effectue les opérations suivantes selon la documentation officielle :
a) Crée un nouvel objet module vide (qui peut contenir plusieurs modules) ; b) Insère cet objet module dans sys.module ; c) Charge le code du module (si nécessaire, il doit d'abord être compilé) (le processus implique de trouver l'emplacement du module : si le module à importer s'appelle m1, l'interprèteur recherche d'abord m1.py dans le répertoire courant, puis dans les variables d'environnement PYTHONPATH) ; d) Exécute le code correspondant dans le nouveau module.
Structure d'un package Python La définition d'un package Python est simple : sa structure hiérarchique correspond à celle des répertoires contenant les fichiers .py. Un point important est qu'un package doit obligatoirement contenir un fichier init.py.
Organisation d'un package Considérons l'organisation suivante :
Répertoire principal : mon_projet Sous-répertoires : utils, outils, main.py
Structure des sous-répertoires : utils : init.py, outils_utils.py outils : init.py, fonctions_outils.py
Le script principal main.py :
from utils import traitement_donnees
from utils import analyse_statistique
from outils import afficher_liste
def fonction_principale():
traitement_donnees()
analyse_statistique()
afficher_liste()
if __name__ == "__main__":
fonction_principale()
Le fichier outils_utils.py :
def traitement_donnees():
print("MODULE_UTILS - traitement des données")
def analyse_statistique():
print("MODULE_UTILS - analyse statistique")
Le fichier init.py dans le répertoire utils :
from .outils_utils import traitement_donnees
from .outils_utils import analyse_statistique
Le symbole . dans .outils_utils indique que outils_utils se trouve dans le même répertoire que init.py.
Ma compréhension personnelle Lorsque main.py exécute l'instruction from utils import traitement_donnees, Python recherche d'abord le package utils et exécute son fichier init.py. Comme ce dernier importe les fonctions traitement_donnees et analyse_statistique depuis outils_utils, ces fonctions deviennent accessibles directement depuis le package utils.
Si nous commentons la ligne d'importation d'une fonction dans init.py, celle-ci ne sera plus accessible via le package, démontrant ainsi que le fichier init.py contrôle ce qui est exposé par le package.
Utilisation des caractères génériques avec allParfois, on souhaite importer tous les éléments d'un module à l'aide de l'astérisque (*). Le mécanisme est contrôlé par init.py via la variable spéciale all.
Dans init.py, on peut spécifier :
__all__ = ['outils_utils']
Si nous définissons plutôt :
__all__ = []
Et que nous essayons d'importer le module, une erreur se produira :
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named outils_utils
Cela confirme que l'importation des modules à l'intérieur d'un package est contrôlée par init.py.
Références mutuelles entre modules Pour référencer d'autres modules au sein d'un même package, une importation directe suffit. Par exemple, dans outils_utils.py, on peut directement importer d'autres modules du même package.
Pour référencer des modules de packages différents, par exemple si outils_utils.py a besoin d'utiliser une fonction de fonctions_outils.py, l'importation doit être explicite :
from outils.fonctions_outils import fonction_specifique
``