Outils personnels
Vous êtes ici : Accueil Python Quoi de neuf dans Python 2.5 PEP 328: Importation relative et absolue

PEP 328: Importation relative et absolue

Par Benjamin Poulain - Dernière modification 18/04/2008 21:03
Contributeurs : Bozo_le_clown
Python License

Python 2.5 introduit l'importation absolue pour l'importation de package, les packages sont importés avec un chemin absolu, et une syntaxe particulière permet d'utiliser un chemin relatif. Ce nouveau comportement est accessible à l'aide de __future__ mais il deviendra le comportement par défaut dans une future version de Python et il est important d'y faire attention dès maintenant dans le code.

La partie la plus simple du PEP 328 était déjà implémentée dans Python 2.4: les parenthèses pouvaient être utilisées pour contenir les noms importés à l'aide d'une directive from ... import ..., rendant ainsi plus simple l'importation de nombreux noms différents.

La partie plus complexe est implémentée à partir de Python 2.5 : l'importation de module peut spécifier un chemin absolu ou relatif au package. Le but est de rendre l'importation absolue le type par défaut dans les prochaines versions de Python.

Disons que vous avez un répertoire comme celui-ci :

pkg/
pkg/__init__.py
pkg/main.py
pkg/string.py

Ceci définit un package nommé pkg contenant les sous-modules pkg.main et pkg.string.

Considérez le code du module main.py. Que se passe-t-il si il exécute l'opération import string ? Avant Python 2.5, l'interpréteur cherchait d'abord dans le dossier du package pour effectuer une importation relative, il trouvait pkg/string.py, et importait le contenu de ce fichier comme module pkg.string, rendant de ce fait ce module lié au nom "string" dans l'espace de nom du module pkg.main.

C'est génial si c'est pkg.string que vous désiriez charger, mais que faire si vous désiriez le module string standard de Python? Il n'y a pas de moyen propre d'ignorer pkg.string et de chercher le module standard; généralement vous aviez à regarder le contenu de sys.modules, ce qui est légèrement inapproprié. Le package py.std de Holger Krekel fournit une méthode plus propre pour importer des modules de la bibliothèque standard, import py ; py.std.string.join(), mais ce package n'est pas disponible sur toutes les installations de Python.

Lire du code qui compte sur les importations relatives est aussi moins clair, parce que le lecteur peut avoir du mal à comprendre quel module l'auteur voulait utiliser. Les utilisateurs Python ont rapidement appris à ne pas utiliser les noms de modules de la bibliothèque standard dans les sous-modules de leurs packages, mais il est impossible de se prémunir contre des noms utilisés dans de nouveaux modules ajoutés dans les versions suivantes de Python.

Dans Python 2.5, vous pouvez changer le comportement de import à l'aide de la directive from __future__ import absolute_import. Ce nouveau comportement absolu de l'importation deviendra le comportement normal dans une version future de Python (probablement Python 2.7). Quand l'importation absolue sera la normale, import string importera toujours la version de la bibliothèque standard. Il est suggéré aux utilisateurs de commencer à utiliser les importations absolues autant que possible, il est ainsi préférable de commencer à écrire from pkg import string dans votre code, plutôt que la version relative.

L'importation relative est toujours possible en ajoutant un point avant le nom du module dans la directive from ... import ... :

# Importe les noms depuis pkg.string
from .string import nom1, nom2
# importe pkg.string
from . import string

Ceci importe le module string en utilisant un chemin relatif au package courant, donc ici, pkg.main importera nom1 et nom2 depuis pkg.string. Des points supplémentaires pour une importation relative permettent de charger un module dans le parent du package courant. Par exemple, ce code placé dans le module A.B.C :

from . import D  # Importe A.B.D
from .. import E # Importe A.E
from ..F import G # Importe A.F.G

Les points précédant le nom pour l'importation relative ne peuvent pas être utilisés avec la forme "import nomDuModule" de la directive d'importation, ils sont uniquement utilisables avec la forme "from ... import ...".

Actions sur le document