Modules Python
Modules et paquets Python
Section titled “Modules et paquets Python”Les modules sont un moyen fondamental d’organiser le code Python. Ils vous permettent de regrouper des fonctions, des classes et des variables connexes dans des fichiers séparés, favorisant la réutilisabilité, la maintenabilité et la structure logique du code. Un module est essentiellement un fichier Python (.py) contenant des définitions et des instructions Python.
Considérez les modules comme des boîtes à outils. Au lieu d’avoir tous vos outils éparpillés partout, vous regroupez les outils connexes (comme des clés ou des tournevis) dans des boîtes spécifiques. Lorsque vous avez besoin d’un outil particulier, vous prenez la bonne boîte à outils (importez le module) et choisissez ensuite l’outil dont vous avez besoin.
Exemple : Création d’un module simple
Section titled “Exemple : Création d’un module simple”Créons un module nommé helpers.py :
"""Un module simple avec des fonctions d'aide."""
PI = 3.14159
def greet(name): """Salue la personne avec le nom donné.""" print(f"Hello, {name}!")
class Calculator: """Une classe de calculatrice de base.""" def add(self, x, y): return x + yL’instruction import
Section titled “L’instruction import”Pour utiliser les définitions d’un module dans un autre fichier Python (par exemple, main.py), vous utilisez l’instruction import. La syntaxe de base est :
import module_name# Ou importer plusieurs modulesimport module1, module2# Ou style préféré (une importation par ligne)import module_oneimport module_twoLorsque Python rencontre import helpers, il recherche helpers.py (ou d’autres types de modules) dans son chemin de recherche. Une fois trouvé, il exécute le code du module (s’il n’a pas déjà été importé) et rend ses définitions disponibles via le préfixe du nom du module.
Exemple (main.py dans le même répertoire que helpers.py) :
import helpers
helpers.greet("Alice")print(f"La valeur de PI est approximativement : {helpers.PI}")
calc = helpers.Calculator()result = calc.add(5, 3)print(f"5 + 3 = {result}")L’exécution de python main.py produit :
Hello, Alice!The value of PI is approximately: 3.141595 + 3 = 8Un module est chargé et exécuté une seule fois, la première fois qu’il est importé lors de l’exécution d’un programme. Les importations ultérieures du même module récupèrent simplement l’objet module déjà chargé.
L’instruction from...import
Section titled “L’instruction from...import”Cette instruction vous permet d’importer des noms spécifiques (fonctions, classes, variables) directement dans l’espace de noms du script actuel, évitant ainsi la nécessité du préfixe du module.
from module_name import name1# Ou importer plusieurs nomsfrom module_name import name1, name2# Ou importer et renommerfrom module_name import name1 as alias_nameExemple :
from helpers import greet, PIfrom helpers import Calculator as Calc # Renommage
greet("Bob")print(f"PI: {PI}")
my_calc = Calc()print(f"10 + 5 = {my_calc.add(10, 5)}")Ceci évite de préfixer avec helpers. mais introduit les noms importés directement dans la portée actuelle. Soyez conscient des potentielles collisions de noms.
L’instruction from...import *
Section titled “L’instruction from...import *”Vous pouvez importer tous les noms publics (ceux ne commençant pas par un underscore _) d’un module en utilisant :
from module_name import *Attention : Cette pratique est généralement déconseillée dans le code de production. Elle importe potentiellement de nombreux noms dans l’espace de noms actuel, ce qui rend incertaine l’origine d’un nom spécifique et augmente le risque de conflits de noms. Elle est acceptable dans les sessions interactives ou parfois dans des schémas de modules spécifiques (__init__.py).
Chemin de recherche des modules
Section titled “Chemin de recherche des modules”Lorsque vous importez my_module, Python le recherche dans cet ordre :
- Le répertoire contenant le script d’entrée (ou le répertoire actuel si en mode interactif).
- Les répertoires listés dans la variable d’environnement
PYTHONPATH(si définie). Le format dépend de la plateforme (par exemple, séparés par des deux-points sur Unix/macOS, par des points-virgules sur Windows). - Chemins par défaut dépendants de l’installation (généralement dans le répertoire
site-packagesde l’installation Python).
Le chemin de recherche est accessible par programme via sys.path, qui est une liste de chaînes de caractères.
import sysprint(sys.path)La variable PYTHONPATH
Section titled “La variable PYTHONPATH”PYTHONPATH est une variable d’environnement que vous pouvez définir pour ajouter des répertoires supplémentaires où Python recherchera des modules. Sa syntaxe reflète celle de la variable PATH du système.
Exemple (Linux/macOS) :
export PYTHONPATH="/home/user/my_python_libs:/another/path"Exemple (Invite de commandes Windows) :
set PYTHONPATH=C:\Users\user\my_python_libs;D:\other_pathBien que PYTHONPATH puisse être utile, la gestion des dépendances avec des environnements virtuels et l’installation standard de paquets (pip) est l’approche moderne préférée.
Espaces de noms et portée
Section titled “Espaces de noms et portée”Un espace de noms est un mappage des noms vers les objets (comme un dictionnaire). Python utilise les espaces de noms pour éviter les collisions de noms.
Python suit la règle LEGB pour la résolution de portée : Local -> Locales de la fonction englobante -> Global -> Intégré.
Pour modifier une variable globale depuis l’intérieur d’une fonction, vous devez utiliser le mot-clé global. Pour modifier une variable dans la portée d’une fonction englobante (dans des fonctions imbriquées), utilisez le mot-clé nonlocal (Python 3+).
x = 100 # Global
def outer_func(): y = 20 # Local englobant def inner_func(): nonlocal y # Modifie la variable de portée englobante global x # Déclare l'intention de modifier la variable globale z = 5 # Local y += 5 x += 1 print(f"Intérieur : x={x}, y={y}, z={z}") inner_func() print(f"Extérieur : x={x}, y={y}")
outer_func()print(f"Global : x={x}")La fonction dir()
Section titled “La fonction dir()”La fonction intégrée dir(), lorsqu’elle est appelée sans arguments, retourne une liste de noms dans la portée locale actuelle. Lorsqu’elle est appelée avec un objet (comme un module) en tant qu’argument, elle retourne une liste triée de noms définis par cet objet (ses attributs, méthodes, etc.).
import math
print(dir(math)) # Liste les noms dans le module math
my_var = 10def my_func(): passprint(dir()) # Liste les noms dans la portée actuelle (globale)La sortie peut inclure des noms spéciaux comme __name__ (nom du module) et __file__ (chemin du fichier du module).
Les fonctions globals() et locals()
Section titled “Les fonctions globals() et locals()”Ces fonctions intégrées retournent des dictionnaires représentant respectivement les espaces de noms global et local.
Rechargement de modules (importlib.reload)
Section titled “Rechargement de modules (importlib.reload)”Les modules sont généralement chargés une seule fois. Si vous modifiez le fichier source d’un module pendant l’exécution de votre programme principal (courant lors du développement interactif ou des applications à long terme), les modifications ne seront pas automatiquement prises en compte. Pour forcer le rechargement d’un module déjà importé, utilisez la fonction importlib.reload() (note : reload était une fonction intégrée en Python 2, mais a été déplacée vers importlib en Python 3).
import importlibimport helpers
# ... code utilisant helpers ...
# Supposons que helpers.py a été modifiéimportlib.reload(helpers)
# Utilisez maintenant la version mise à jour de helpershelpers.greet("Utilisateur mis à jour")Utilisez reload avec prudence, car cela peut entraîner des incohérences si ce n’est pas géré attentivement, surtout avec des dépendances complexes ou des objets à état.
Paquets en Python
Section titled “Paquets en Python”Les paquets offrent un moyen de structurer l’espace de noms des modules de Python en utilisant des « noms de modules à points ». Un paquet est essentiellement un répertoire contenant des modules Python et potentiellement d’autres sous-paquets. Pour être reconnu comme un paquet régulier (avant Python 3.3, et toujours une pratique courante), le répertoire doit contenir un fichier nommé __init__.py (qui peut être vide).
Exemple de structure :
sound/ __init__.py formats/ __init__.py wavread.py aiffread.py ... effects/ __init__.py echo.py surround.py ... filters/ __init__.py equalizer.py ...Vous pouvez importer des modules à partir de paquets en utilisant la notation pointée :
import sound.effects.echosound.effects.echo.apply_echo(...)
from sound.formats import wavreadwavread.read_wavfile(...)
from sound.filters.equalizer import Equalizereq = Equalizer()Le fichier __init__.py
Section titled “Le fichier __init__.py”Le fichier __init__.py sert à plusieurs fins :
Exemple (sound/effects/__init__.py) :
print("Initialisation du paquet d'effets sonores...")
# Rend echo et surround disponibles directement via 'from sound.effects import ...'from . import echofrom . import surround
# Contrôle 'from sound.effects import *'__all__ = ["echo", "surround"]Avec ce __init__.py, vous pourriez faire :
import sound.effects
sound.effects.echo.apply_echo(...) # Accès via sous-moduleNote : Python 3.3 a introduit les paquets d’espace de noms implicites (Implicit Namespace Packages, PEP 420), qui permettent de créer des paquets sans fichier __init__.py, principalement utiles pour diviser un seul grand paquet entre plusieurs répertoires.