Два модуля Python требуют содержимого друг друга - может ли это работать?
у меня есть модуль веб-сервера бутылки со следующей строкой:
from foobar.formtools import auto_process_form_insert
и foobar.formtools
модуль содержит эту строку:
from foobar.webserver import redirect, redirect_back
конечно, оба результата приводят к следующим ошибкам (соответственно):
ImportError: не удается импортировать имя auto_process_form_insert
ImportError: не удается импортировать имя перенаправить
это просто факт, что в Python два модуля не могут импортировать друг друга, и весь импорт модулей должен быть иерархическая по своей природе, или я делаю что-то не так? В качестве альтернативы, есть ли обходной путь, кроме размещения всех этих приятных функций в новых модулях?
2 ответов
модули можете импорт друг друга циклически, но есть загвоздка. В простом случае, он должен работать, двигая import
операторы в нижней части файла или не используя from
синтаксис.
вот почему это работает:
при импорте модуля Python сначала проверяет sys.modules
. Если он там, он просто импортируется оттуда. Если его нет, он пытается импортировать его обычным способом; в основном, он находит файл и запускает материал в он.
запуск модуля заполняет содержимое модуля. Например, скажем, у нас есть этот модуль с творческим именем example_opener
:
import webbrowser
def open_example():
webbrowser.open('http://www.example.com/')
в начале, модуль пуст. Затем Python выполняет:
import webbrowser
после этого, модуль содержит только webbrowser
. Затем Python выполняет следующее:
def open_example():
webbrowser.open('http://www.example.com/')
Python создает open_example
. Теперь модуль содержит webbrowser
и open_example
.
сказать webbrowser
содержащиеся в этом код:
from example_opener import open_example
def open(url):
print url
сказать example_opener
импортированный в первую очередь. Выполняется следующий код:
import webbrowser
webbrowser
еще не импортирован, поэтому Python выполняет содержимое webbrowser
:
from example_opener import open_example
example_opener
и импортировано, но еще не полностью выполнено. Питону все равно. Python вытаскивает модуль из sys.modules
. В этот момент example_opener
по-прежнему пуст. Он не определил open_example
еще, даже не завершен импорт webbrowser
. Python не может найти open_example
на example_opener
, поэтому он терпит неудачу.
что делать, если мы импортировали open_example
С конца webbrowser
и webbrowser
С конца example_opener
? Python начнет с выполнения этого кода:
def open_example():
webbrowser.open('http://www.example.com/')
webbrowser
еще не существует, но это не имеет значения, пока open_example
называется. Теперь example_opener
содержит только open_example
. Затем он выполняет:
import webbrowser
он еще не был импортирован, поэтому Python выполняет webbrowser
. Он начинает:
def open(url):
print url
это определяет open
. Затем он выполняет:
from example_opener import open_example
example_opener
находится в sys.modules
, поэтому он использует это. example_opener
содержит open_example
, так что это удается. Python завершает импорт webbrowser
. Это завершает импорт webbrowser
С example_opener
. Это последняя вещь в example_opener
, так что импорт example_opener
финиши, успешные, также.