Два модуля 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 финиши, успешные, также.


не from ... import .... Просто сделай!--1--> и ссылки на его объекты, используя имя модуля.