2012-04-30 2 views
0

У меня есть 3 проекта, созданных в PyDev, которые имеют друг друга в списке проектов. для целей иллюстрации:круглые импортные наземные мины с латуком

proj_f 
    pack_foo 
     mod_fooa (contains class Fooa) 
     mod_foob (contains class Foob) 
    mod_faa (contains class Faa) 
    pack_fii 
     mod_fiia (contains class Fiia) 
     mod_fiib (contains class Fiib) 
proj_b 
    mod_bar (contains function func_bar) 
    pack_baz 
     mod_baza (contains class Baza) 
     mod_bazb (contains class Bazb) 
proj_t 
    tester (what I'm running from) 

Ради примера снова, тестер:

from pack_foo.mod_fooa import Fooa 
from pack_fii.mod_fiia import Fiia 
from mod_bar import func_bar 
func_bar(Fooa(), Fiia()) 

и mod_bar:

from pack_foo.mod_fooa import Fooa 
from pack_fii.mod_fiia import Fiia 
def func_bar(fooa, fiia): 
    if not fooa: 
     fooa = Fooa() 
    if not fiia: 
     fiia = Fiia() 
    fooa.do_magic() 
    fiia.do_magic() 

Что я вижу в том, что некоторые импорт из обув получит ImportError: cannot import name в mod_bar, когда я вызываю их из тестера (особенно, некоторые, но не все). Если я запускаю только mod_bar, импорт работает нормально, если я удаляю зависимости и импорт из mod_bar и запускаю его из тестера, он отлично работает; он только ломается, если подмножество классов импортируется из f в в b и t и я запускаю из t. Я пробовал читать документы о том, как импорт работает и подходит для решений, но я не нашел ничего, что указывало мне в правильном направлении. У меня такое чувство, что это связано с какой-то неясной частью внутренних элементов Python, но я не знаю достаточно, чтобы знать, что это такое.

Я думаю, что это точно отражает то, что происходит, хотя есть дополнительный уровень сложности участвует в том, что ссылка от tester к mod_bar является косвенным (tester файл я использую, чтобы обезьяна вокруг с моим кодом, как я работаю на он, в то время как mod_bar на самом деле является файлом ландшафта латука, а Lettuce загружается некоторыми другими модулями, которые вызывает tester.) Может ли кто-нибудь предоставить мне хотя бы какое-то место, чтобы начать поиск информации о том, как преодолеть эту проблему?

Edit:

Я смотрел на этого еще, в частности трассировки стека:

Traceback (most recent call last): 
    File "C:\Python27\Lib\site-packages\lettuce\__init__.py", line 53, in <module> 
    terrain = fs.FileSystem._import("terrain") 
    File "C:\Python27\Lib\site-packages\lettuce\fs.py", line 74, in _import 
    module = imp.load_module(name, fp, pathname, description) 
    File "C:\Users\adminsetup\workspace\nytd_lettuce_lib\terrain.py", line 6, in <module> 
    from session.session import Session 
    ImportError: cannot import name Session 

Может terrain = fs.FileSystem._import("terrain") в lettuce.__init__() быть причиной круговыми импорта, которые дают мне эти головные боли?

ответ

0

Так что да, я получал круговой импорт. Проблема в том, что когда вы import lettuce, lettuce.py выполняет, который затем динамически импортирует terrain.

Что происходило со мной в том, что у меня есть класс Session, который импортирует AbstractSession, который в свою очередь, импорт LoggerManager, который содержит logging.Handler подкласс, который выталкивает сообщения журнала в очереди в world, и, таким образом, делает logger_manager import lettuce для доступа world. Я также хотел, чтобы все мои тесты начинались с вращения объекта Session, поэтому у меня есть метод @beforeeach на местности, чтобы начать сеанс перед каждым тестом, а это означает импорт сеанса на местности.

Конечно, это означает, что каждый раз, когда я импортирую сеанс в любом файле в любом месте, он запускает целую цепочку событий (Session> AbstractSession> lettuce> terrain> Session), которая оставляет session.session.Session не инициализируется к моменту времени рельеф пытается загрузить его.

Я считаю, что мое лучшее исправление заключается в том, чтобы привязать обработчик журнала и кэш журналов, которые связаны с миром в местности, а затем привязать к нему обработчик. К счастью, это вариант для меня, поскольку ведение журнала - это глобальный доступ. Это на самом деле несколько улучшает компартиментацию моего фреймворка, поскольку в базовых библиотеках не будет никакого кода, который говорит о салате, который все будет в libtuce lib. Тем не менее, было бы лучше, если бы у салата не было этих наземных мин, построенных ...

tl; dr, избегайте салата, если вы хотите попробовать сделать что-то большее, чем действительно базовые комплекты тестов.