J'ai récemment mis à jour des versions de pylint , un populaire vérificateur de style Python.
Il est devenu balistique tout au long de mon code, indiquant les endroits où j'importe des modules dans le même package, sans spécifier le chemin complet du package.
Le nouveau message d'erreur est W0403.
W0403: Importation relative% r, doit être% r
Utilisé lorsqu'une importation relative au répertoire du package est détectée.
Par exemple, si mes packages sont structurés comme ceci:
/cake
/__init__.py
/icing.py
/sponge.py
/drink
et dans le paquet éponge j'écris:
import icing
au lieu de
import cake.icing
J'obtiendrai cette erreur.
Bien que je comprenne que tous les messages Pylint n'ont pas la même importance et que je n'ai pas peur de les rejeter, je ne comprends pas pourquoi une telle pratique est considérée comme une mauvaise idée.
J'espérais que quelqu'un pourrait expliquer les pièges, afin que je puisse améliorer mon style de codage plutôt que (comme je prévois actuellement de le faire) de désactiver cet avertissement apparemment faux.
Le problème de import icing
est que vous ne savez pas s'il s'agit d'une importation absolue ou d'une importation relative. icing
pourrait un module dans le chemin de python, ou un package dans le module actuel. C'est assez ennuyeux lorsqu'un package local porte le même nom qu'un package de bibliothèque standard python.
Tu peux faire from __future__ import absolute_import
qui désactive complètement les importations relatives implicites. Il est décrit, y compris avec cette justification de l'ambiguïté, dans PEP 328 . Je crois que Python 3000 a des importations relatives implicites complètement désactivées.
Vous pouvez toujours faire des importations relatives, mais vous devez les faire explicitement, comme ceci:
from . import icing
Il y a quelques bonnes raisons:
Les importations relatives se cassent facilement lorsque vous déplacez un module.
Imaginez que vous avez un foo.bar
, une foo.baz
et un module baz
dans votre package. foo.bar
importe foo.baz
, mais en utilisant une importation relative.
Maintenant, si vous déménagiez foo.bar
à bar
, votre module importe soudainement un autre baz
!
Les importations relatives sont ambiguës. Même sans se déplacer dans le module bar
dans l'exemple ci-dessus, un nouveau développeur venant à votre projet pourrait être pardonné de ne pas se rendre compte que baz
est vraiment foo.baz
au lieu du package de niveau racine baz
.
Les importations absolues indiquent clairement quel module est utilisé. Et comme import this
prêche, explicite vaut mieux qu'implicite.
Python 3 a complètement désactivé les importations relatives implicites; les importations sont désormais toujours interprétées comme absolues, ce qui signifie que dans l'exemple ci-dessus import baz
importera toujours le module de niveau supérieur. Vous devrez utiliser la syntaxe d'importation explicite à la place (from . import baz
).
Porter l'exemple de Python 2 à 3 entraînerait donc des problèmes inattendus, l'utilisation des importations absolues maintenant rendra votre code à l'épreuve du temps.