Historique de la question : Les packages sont apparus en Python pour structurer de grandes bases de code et pour la réutilisation du code. Ils permettent de diviser un projet en modules logiques et facilitent la maintenance et l'importation des fonctionnalités nécessaires.
Problème : Une compréhension incorrecte de la structure des packages entraîne des erreurs d'importation, des conflits de noms et des erreurs lors de l'exécution des scripts. Il est important de connaître la différence entre les packages et les modules, ainsi que les règles de travail avec les imports relatifs et absolus.
Solution :
Un package est tout répertoire contenant un fichier __init__.py (vide ou avec du code d'initialisation). Les packages peuvent contenir d'autres packages et modules. Exemple de structure :
project/
├── mypackage/
│ ├── __init__.py
│ ├── mod1.py
│ └── subpackage/
│ ├── __init__.py
│ └── mod2.py
└── script.py
Pour l'importation, nous utilisons le chemin relatif (from .subpackage import mod2) ou absolu (from mypackage.subpackage import mod2). Les chemins absolus sont préférables pour les grands projets.
Caractéristiques clés :
__init__.pyLe fichier init.py doit-il obligatoirement être présent dans chaque dossier que nous voulons transformer en package ?
Oui, pour Python version inférieure à 3.3 ; dans les versions modernes de Python (3.3+), il existe des « packages de namespace » « implicites », mais pour une compatibilité totale, le fichier est tout de même recommandé.
Que se passe-t-il si on importe un package au lieu d'un module ?
Seul le code de __init__.py de ce package sera exécuté.
Quelle est la différence entre l'importation “from . import mod1” et “import mod1” ?
from . import mod1 (importation relative) ne fonctionne que dans le package, tandis que l'importation absolue cherche le module dans sys.path, ce qui peut entraîner des conflits de noms.
__init__.pyCas négatif : Des modules avec des noms identiques dans différents sous-dossiers sans utilisation des imports absolus. Un module est accédé par le mauvais package, ce qui était prévu. Avantages :
Cas positif :
Déclaration explicite des imports absolus, structure de dossiers correcte et présence de __init__.py.
Avantages :