web-dev-qa-db-fra.com

Importation relative absolue vs explicite de Python

Je me demande quelle est la meilleure façon d'importer des packages dans une application Python. J'ai une structure de package comme celle-ci:

project.app1.models
project.app1.views
project.app2.models

project.app1.views importe project.app1.models et project.app2.models. Il y a deux façons de le faire qui me viennent à l'esprit.

Avec des importations absolues:

import A.A
import A.B.B

ou avec des importations relatives explicites, comme introduit dans Python 2.5 avec PEP 328 :

# explicit relative
import ..A
import .B

Quelle est la façon la plus Pythonique de procéder?

72
Daniel Hepper

Importations absolues. Depuis PEP 8:

Les importations relatives pour les importations intra-colis sont fortement déconseillées. Utilisez toujours le chemin absolu du package pour toutes les importations. Même maintenant que PEP 328 [7] est entièrement implémenté en Python 2.5, son style d'importations relatives explicites est activement déconseillé; les importations absolues sont plus portables et généralement plus lisibles.

Les importations relatives explicites sont une fonctionnalité linguistique agréable (je suppose), mais elles ne sont pas aussi explicites que les importations absolues. La forme la plus lisible est:

import A.A
import A.B.B

surtout si vous importez plusieurs espaces de noms différents. Si vous regardez des projets/tutoriels bien écrits qui incluent des importations à partir de packages, ils suivent généralement ce style.

Les quelques frappes supplémentaires que vous prenez pour être plus explicites permettront aux autres (et peut-être à vous) de gagner beaucoup de temps à l'avenir lorsqu'ils essaieront de comprendre votre espace de noms (surtout si vous migrez vers 3.x, dans lequel une partie du package les noms ont changé).

42
Rafe Kettler

Les importations relatives Python ne sont plus fortement déconseillées, mais l'utilisation d'absolu_import est fortement suggérée dans ce cas.

Veuillez voir cette discussion citant Guido lui-même:

"N'est-ce pas principalement historique? Jusqu'à l'implémentation de la nouvelle syntaxe d'importation relative, il y avait divers problèmes avec les importations relatives. La solution à court terme était de recommander de ne pas les utiliser. La solution à long terme était d'implémenter une syntaxe sans ambiguïté. Maintenant il est temps de retirer l'anti-recommandation. Bien sûr, sans aller trop loin - je leur trouve encore un goût acquis; mais ils ont leur place. "

L'OP relie correctement le PEP 328 qui dit:

Plusieurs cas d'utilisation ont été présentés, dont le plus important est de pouvoir réorganiser la structure de gros packages sans avoir à éditer des sous-packages. De plus, un module à l'intérieur d'un package ne peut pas facilement s'importer sans importations relatives.

Voir également la question presque en double Quand et pourquoi utiliser les importations relatives en Python

Bien sûr, c'est toujours une question de goût. Bien qu'il soit plus facile de déplacer le code avec des importations relatives, cela peut également casser les choses de manière inattendue; et renommer les importations n'est pas si difficile.

Pour forcer le nouveau comportement à partir de PEP 328, utilisez:

from __future__ import absolute_import

Dans ce cas, l'importation relative implicite ne sera plus possible (par exemple. import localfile ne fonctionnera plus, seulement from . import localfile). Pour un comportement propre et à l'épreuve du temps, l'utilisation de Absolute_import est recommandée.

Une mise en garde importante est qu'en raison de PEP 338 et PEP 366 , les importations relatives nécessitent que le fichier python soit importé en tant que module - vous ne peut pas exécuter un fichier.py qui a une importation relative ou vous obtiendrez un ValueError: Attempted relative import in non-package.

Cette limitation doit être prise en compte lors de l'évaluation de la meilleure approche. Guido est contre l'exécution de scripts à partir d'un module dans tous les cas:

Je suis -1 sur ce point et sur tout autre twiddlings proposé de la machine __main__. Le seul cas d'utilisation semble être l'exécution de scripts qui se trouvent à l'intérieur d'un répertoire de module, que j'ai toujours vu comme un contre-modèle. Pour me faire changer d'avis, il faudrait me convaincre que non.

Des discussions exhaustives sur la question peuvent être trouvées sur SO; ré. Python 3 c'est assez complet:

111
Stefano

Les importations relatives vous permettent non seulement de renommer votre package plus tard sans modifier des dizaines d'importations internes, mais j'ai également réussi à résoudre certains problèmes impliquant des choses comme les importations circulaires ou les packages d'espace de noms, car ils n'envoient pas Python "retour en haut" pour recommencer la recherche du module suivant à partir de l'espace de noms de niveau supérieur.

30
Brandon Rhodes