
Importer des modules (import, from ... import ...)
Maîtrisez l'importation de modules en Python. Découvrez les différentes syntaxes ('import', 'from ... import ...'), comprenez la gestion des namespaces, et apprenez à éviter les conflits de noms.
Qu'est-ce qu'un module en Python ? Organisation du code
En Python, un module est un fichier contenant du code Python (définitions de fonctions, de classes, de variables, etc.). Les modules permettent d'organiser le code de manière logique et de le réutiliser facilement.
Un module peut être :
- Un fichier Python simple (avec l'extension `.py`).
- Un package (un répertoire contenant plusieurs fichiers Python, ainsi qu'un fichier spécial `__init__.py`).
- Un module écrit en C, compilé et lié dynamiquement à l'interpréteur Python (comme le module `math`).
Les modules sont essentiels pour structurer les projets Python de grande taille. Ils permettent de diviser le code en unités logiques, de gérer les dépendances, et d'éviter les conflits de noms.
L'instruction `import` permet d'accéder au code défini dans un module et de l'utiliser dans votre propre code.
import module : importer un module entier
La forme la plus simple d'importation est `import module`. Cette instruction importe le module spécifié et le rend accessible dans l'espace de noms courant.
Syntaxe :
import nom_du_moduleExemple :
import math
print(math.sqrt(16)) # Affiche 4.0 (utilisation de la fonction sqrt du module math)Après `import math`, vous accédez aux fonctions, classes, et variables définies dans le module `math` en utilisant la notation `math.nom` (par exemple, `math.sqrt`, `math.pi`, `math.sin`).
Vous pouvez importer plusieurs modules en une seule instruction, en les séparant par des virgules :
import math, os, sysCependant, il est généralement recommandé d'importer chaque module sur une ligne séparée, pour une meilleure lisibilité.
import module as alias : importer avec un alias
Vous pouvez importer un module et lui donner un alias (un nom plus court ou différent) en utilisant le mot-clé `as`.
Syntaxe :
import nom_du_module as aliasExemple :
import math as m # Importe le module math et lui donne l'alias m
print(m.sqrt(16)) # Affiche 4.0Les alias sont souvent utilisés pour :
- Raccourcir les noms de modules longs (par exemple, `import matplotlib.pyplot as plt`).
- Eviter les conflits de noms si vous avez un module local avec le même nom qu'un module de la bibliothèque standard.
- Améliorer la lisibilité du code.
from module import nom1, nom2, ... : importer des noms spécifiques
L'instruction `from module import nom1, nom2, ...` permet d'importer des noms spécifiques (fonctions, classes, variables) définis dans un module, directement dans l'espace de noms courant. Vous pouvez ensuite utiliser ces noms directement, sans avoir à les préfixer par le nom du module.
Syntaxe :
from nom_du_module import nom1, nom2, nom3Exemple :
from math import sqrt, pi
print(sqrt(16)) # Affiche 4.0 (pas besoin d'écrire math.sqrt)
print(pi) # Affiche 3.141592653589793 (pas besoin d'écrire math.pi)Vous pouvez importer tous les noms d'un module avec `from module import *`. Cependant, **cette pratique est généralement déconseillée**, car elle peut polluer l'espace de noms courant et rendre le code plus difficile à comprendre (il devient difficile de savoir d'où viennent les noms).
Exemple (déconseillé) :
from math import *
print(sin(pi / 2)) # Affiche 1.0 (mais on ne sait pas immédiatement que sin vient de math)Il est préférable d'importer explicitement les noms dont vous avez besoin, ou d'utiliser `import module` et d'accéder aux noms avec `module.nom`.
from module import nom as alias : importer un nom spécifique avec un alias
Vous pouvez combiner `from ... import` et `as` pour importer un nom spécifique d'un module et lui donner un alias.
Syntaxe:
from nom_du_module import nom as aliasExemple:
from math import sqrt as racine_carree
print(racine_carree(16)) # Affiche 4.0Cela peut être utile pour éviter les conflits de noms, ou pour donner un nom plus descriptif à une fonction ou une classe.
Namespaces (espaces de noms) : éviter les conflits de noms
Les namespaces (espaces de noms) sont un mécanisme important en Python pour éviter les conflits de noms. Un namespace est un conteneur qui associe des noms (de variables, de fonctions, de classes, etc.) à des objets.
Chaque module a son propre namespace. Lorsque vous utilisez `import module`, vous importez le module dans un namespace séparé. Vous accédez ensuite aux noms définis dans ce module en utilisant la notation `module.nom`.
Lorsque vous utilisez `from module import nom`, vous importez le nom `nom` directement dans le namespace courant. Il n'y a plus de séparation. Cela peut entraîner des conflits de noms si vous avez déjà un nom identique dans votre code.
Exemple (illustrant un conflit de noms) :
def sqrt(x):
return x ** 0.5 # Notre propre fonction sqrt (racine carrée)
from math import sqrt # Ecrase notre fonction sqrt par celle de math !
print(sqrt(16)) # Affiche 4.0 (utilise la fonction sqrt de math, pas la nôtre)Pour éviter ce conflit, vous pourriez utiliser `import math` et appeler `math.sqrt()`, ou utiliser `from math import sqrt as sqrt_math`.
Bonnes pratiques d'importation
Voici quelques bonnes pratiques pour l'importation de modules en Python :
- Placez les instructions `import` au début du fichier : C'est la convention en Python. Cela permet de voir immédiatement quelles sont les dépendances du module.
- Importez chaque module sur une ligne séparée : `import math`
`import os`
est préférable à `import math, os`. - Groupez les importations : Groupez les importations de la bibliothèque standard, puis les importations de bibliothèques tierces, puis les importations de modules locaux, avec une ligne vide entre chaque groupe.
- Evitez `from module import *` : Préférez importer explicitement les noms dont vous avez besoin, ou utilisez `import module` et accédez aux noms avec `module.nom`.
- Utilisez des alias si nécessaire : Pour raccourcir les noms de modules longs, ou pour éviter les conflits de noms.
- Importez au niveau le plus haut possible : Si vous avez besoin d'un module dans plusieurs fonctions, importez-le au niveau du module, plutôt que de l'importer à l'intérieur de chaque fonction.
- (Avancé) Evitez les importations cycliques : Si le module A importe le module B, et que le module B importe le module A, vous avez une importation cyclique. Cela peut entraîner des problèmes. Il existe des techniques pour résoudre les importations cycliques, mais il est préférable de les éviter en restructurant votre code.
Exemple de code respectant les bonnes pratiques:
# Importations de la bibliothèque standard
import math
import os
import sys
# Importations de bibliothèques tierces
import requests
# Importations de modules locaux
from . import mon_module # Importation relative (voir section suivante)
# ... Reste du code ...Importations relatives et absolues (pour les packages)
Lorsque vous travaillez avec des packages (des répertoires contenant plusieurs modules Python), vous pouvez utiliser des importations relatives ou absolues.
- Importation absolue : Spécifie le chemin complet du module à importer, à partir de la racine du projet. C'est la méthode recommandée lorsque vous importez des modules qui ne font pas partie du même package.
- Importation relative : Spécifie le chemin du module à importer, par rapport au module courant. Cela utilise la notation `.` (pour le répertoire courant) et `..` (pour le répertoire parent).
Exemple (structure de répertoire) :
mon_package/
__init__.py
module_a.py
module_b.py
sous_package/
__init__.py
module_c.pyDans `module_a.py`:
# Importation absolue de module_b (du même package)
import mon_package.module_b
# Importation relative de module_b (du même package)
from . import module_b
# Importation absolue de module_c (d'un sous-package)
import mon_package.sous_package.module_c
# Importation relative de module_c (d'un sous-package)
from .sous_package import module_cDans `module_c.py`:
# Importation relative de module_a (du package parent)
from .. import module_aLes importations relatives sont utiles à l'intérieur d'un package pour importer d'autres modules du même package. Elles permettent de rendre le code plus portable et de faciliter la refactorisation. Cependant, elles peuvent rendre le code plus difficile à comprendre si elles sont utilisées de manière excessive ou si la structure du package est complexe.
Depuis Python 3, les importations relatives *implicites* (sans le `.` initial) ne sont plus autorisées. Vous devez utiliser soit une importation absolue, soit une importation relative explicite.