5 votes

erreur python "No module named" lors de l'appel d'un sous-module

J'ai des problèmes avec l'instruction d'importation car Python signale qu'il n'existe pas de module nommé the_page ou the_generator.

task_a.py contient import generator.the_page as ThePage et lorsqu'il est exécuté en tant que script principal, il ne pose aucun problème.

the_generator.py contient import tasks.task_a mais quand je l'exécute en tant que script principal, python jette l'erreur suivante

Traceback (most recent call last):
  File "/generator/the_generator.py", line 7, in <module>
    import tasks.tasks_a
  File "/generator/tasks/tasks_a.py", line 3, in <module>
    import generator.the_page as ThePage
ImportError: No module named the_page

Voici la structure.

generator/
    __init__.py
    the_generator.py
    the_page.py
    tasks/
        __init__.py
        task_a.py

Vous pouvez peut-être m'aider à résoudre mon problème. Merci pour votre aide !

10voto

abarnert Points 94246

Exécuter scripts à partir du milieu d'un paquet est une mauvaise idée, pour un certain nombre de raisons, dont la plus évidente est celle que vous rencontrez : Lorsque vous import generator.the_generator quelque part, generator finit par être un paquet, donc une importation absolue de generator.the_page ou une importation relative, fonctionnera parfaitement. Mais lorsque vous exécutez simplement le script generator/the_generator.py il n'y a pas de generator.the_generator juste __main__ et il n'y a pas de generator paquet. La seule autre façon dont Python pourrait savoir comment trouver generator.the_page serait si le répertoire parent de generator étaient sur sys.path ce qui n'est pas le cas.

Comme vous pouvez le deviner, vous peut contourner ce problème en brossant sys.path pour y mettre le répertoire parent approprié mais c'est aussi une mauvaise idée.

Cette solution présente également de nombreux autres problèmes. Plus sérieusement, elle peut très facilement conduire à ce que le même module soit importé deux fois (car Python n'a aucun moyen de savoir que deux noms apparemment sans rapport se trouvent faire référence au même module). Elle est également difficile à déployer (vous ne pouvez pas installer un script à /usr/local/bin s'il dépend de l'intérieur d'un paquet ), il ne fonctionnera pas si votre paquet est extrait d'un .zip ou d'un .egg, etc.


Il existe deux façons standard de résoudre ce problème.

Tout d'abord, il suffit d'exécuter le script comme un module plutôt que comme un script. Depuis le répertoire parent de generator juste python -m generator.the_generator au lieu de python generator/the_generator.py .

L'un des principaux avantages de cette méthode est qu'elle fonctionne tout aussi bien dans les déploiements installés normaux, lorsque generator est dans les paquets du site quelque part, comme dans testing.

Alternativement, créez un script qui se trouve à côté de generator et lancez-la, pas un module à l'intérieur. Cela peut être aussi trivial que de déplacer tous les modules de la section if __name__ == '__main__': code dans the_generator.py en une fonction, puis en écrivant un wrapper de deux lignes :

import generator.the_generator
generator.the_generator.main()

Encore une fois, cela fonctionne tout aussi bien dans les déploiements installés normaux. De plus, cela signifie que le script peut être installé dans votre système de gestion de l'information. bin ce qui rend les choses encore plus faciles, tout comme pip o ipython .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X