Nous avons vu comment les scripts et programmes Python peuvent atteindre une taille considérable. Pour gérer la complexité et garder notre code propre et lisible, nous pouvons structurer notre programme en utilisant des modules et des packages. En Python, un module est simplement un fichier contenant du code Python. Les modules peuvent importer d'autres modules, ce qui peut conduire à des modules imbriqués. Les packages, quant à eux, sont un moyen d'organiser des modules liés entre eux dans une hiérarchie de répertoires.
Supposons que vous développez un jeu et que vous avez différentes fonctionnalités telles que sound, level, character, etc., qui sont chacune divisées en leurs propres modules. Maintenant, le module sound lui-même a plusieurs composants, par exemple effects, filters, echo, et ainsi de suite. Dans un tel scénario, vous pouvez créer un module imbriqué. Voyons comment le créer :
Tout d'abord, nous créons un répertoire (dossier) pour notre package. Par exemple, nous pourrions appeler ce répertoire game :
game/ # Le répertoire de notre package de jeu
À l'intérieur du répertoire game, nous créons le répertoire sound et un fichier vide __init__.py. Le fichier __init__.py est nécessaire pour que Python traite les répertoires comme contenant des packages.
game/
sound/ # Sous-répertoire pour le module 'sound'
__init__.py # Permet à Python de traiter 'sound' comme un package
Maintenant, nous pouvons créer différents fichiers Python à l'intérieur du répertoire sound pour effects, filters et echo. Chacun de ces fichiers représente un sous-module du module sound.
game/
sound/
__init__.py
effects.py # Le sous-module 'effects'
filters.py # Le sous-module 'filters'
echo.py # Le sous-module 'echo'
Disons que effects.py ressemble à ceci :
def echo_filter(soundwave):
return soundwave + '...' # Ajoute un écho à l'onde sonore
def distort_filter(soundwave):
return soundwave[::-1] # Inverse l'onde sonore pour créer une distorsion
Si nous voulons utiliser ces fonctions dans un autre module au sein de notre package game, nous pouvons les importer. Nous utilisons un point (.) pour naviguer dans le package. Voici un exemple dans un fichier hypothétique gameplay.py :
Rappelez-vous, organiser votre code Python en modules et packages peut aider à le garder propre et lisible, ainsi qu'à le rendre plus facile à maintenir et à développer.
Le rôle de init.py dans les packages Python
En Python, le fichier __init__.py joue un rôle spécial pour les répertoires que vous souhaitez utiliser comme packages Python. Traditionnellement, un fichier __init__.py était requis pour que Python reconnaisse un répertoire comme un package contenant des modules. Cependant, dans les versions plus récentes de Python (3.3 et ultérieures), grâce à l'introduction des packages de namespace implicites, ce n'est plus strictement nécessaire.
Mais même avec ce changement, les fichiers __init__.py sont loin d'être obsolètes et maintiennent leur utilité dans certaines situations. Par exemple, ils peuvent être utilisés pour exécuter du code d'initialisation du package, contrôler les importations avec la variable __all__, ou définir des importations pratiques. Considérons cette structure de répertoires :
Dans game/sound/__init__.py, nous pourrions avoir :
from .effects import echo_filter
from .filters import distort_filter
from .echo import echo_sound
Ici, nous importons les sous-modules dans le fichier __init__.py. Maintenant, les sous-modules effects, filters et echo peuvent être directement accessibles lorsque nous importons sound. Ainsi, dans une autre partie du programme, vous pourriez faire :
Dans cet exemple, __init__.py joue un rôle crucial en consolidant divers sous-modules et en fournissant une interface simplifiée pour l'importation de fonctionnalités. Bien que les versions plus récentes de Python n'imposent pas la présence de __init__.py, l'utiliser de cette manière peut rendre vos packages plus faciles à utiliser et à gérer.