J'ai un module de serveur Web de bouteille avec la ligne suivante:
from foobar.formtools import auto_process_form_insert
Et le foobar.formtools
le module contient cette ligne:
from foobar.webserver import redirect, redirect_back
Bien sûr, les deux entraînent les erreurs suivantes (respectivement):
ImportError: impossible d'importer le nom auto_process_form_insert
ImportError: impossible d'importer la redirection de nom
Est-ce simplement un fait qu'en Python deux modules ne peuvent pas s'importer l'un l'autre et que toutes les importations de modules doivent être de nature hiérarchique, ou suis-je en train de faire quelque chose de mal? placer toutes ces fonctions Nice dans de nouveaux modules?
Modules can importez-vous cycliquement, mais il y a un hic. Dans le cas simple, cela devrait fonctionner en déplaçant les instructions import
au bas du fichier ou en n'utilisant pas la syntaxe from
.
Voici pourquoi cela fonctionne:
Lorsque vous importez un module, Python vérifie d'abord sys.modules
. Si c'est là-dedans, il importe juste à partir de là. S'il n'est pas là, il essaie de l'importer normalement; en gros, il trouve le fichier et y exécute le contenu.
L'exécution d'un module remplit le contenu du module. Par exemple, supposons que nous ayons ce module, nommé de manière créative example_opener
:
import webbrowser
def open_example():
webbrowser.open('http://www.example.com/')
Au début, le module est vide. Alors Python exécute:
import webbrowser
Après cela, le module ne contient que webbrowser
. Alors Python exécute ceci:
def open_example():
webbrowser.open('http://www.example.com/')
Python crée open_example
. Maintenant, le module contient webbrowser
et open_example
.
Supposons que webbrowser
contenait ce code:
from example_opener import open_example
def open(url):
print url
Dire example_opener
est importé en premier. Ce code est exécuté:
import webbrowser
webbrowser
n'a pas encore été importé, donc Python exécute le contenu de webbrowser
:
from example_opener import open_example
example_opener
a a été importé, mais pas encore entièrement exécuté. Python ne se soucie pas. Python extrait le module de sys.modules
. À ce point, example_opener
est toujours vide. Il n'a pas défini open_example
encore, ni même terminé l'importation webbrowser
. Python ne trouve pas open_example
dans example_opener
, donc ça échoue.
Et si nous importions open_example
à partir de la fin de webbrowser
et webbrowser
à partir de la fin de example_opener
? Python commencerait par exécuter ce code:
def open_example():
webbrowser.open('http://www.example.com/')
webbrowser
n'existe pas encore, mais cela n'a pas d'importance avant que open_example
est appelé. Maintenant example_opener
ne contient que open_example
. Il exécute ensuite:
import webbrowser
Il n'a pas encore été importé, donc Python exécute webbrowser
. Il démarre:
def open(url):
print url
Il définit open
. Ensuite, il exécute:
from example_opener import open_example
example_opener
est dans sys.modules
, donc il utilise ça. example_opener
contient open_example
, donc ça réussit. Python termine l'importation de webbrowser
. Cela conclut l'importation de webbrowser
de example_opener
. C'est la dernière chose dans example_opener
, donc l'importation de example_opener
se termine également.
Ne faites pas from ... import ...
. Faites simplement import ...
et référencer ses objets en utilisant le nom du module.