与生菜的圆形进口地雷

时间:2012-04-30 20:00:36

标签: python import project pydev lettuce

我在PyDev中设置了3个项目,它们在项目引用列表中都有相互关系。用于说明目的:

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()

我所看到的是,当我从测试人员调用它们时,从foo导入的一些内容会在mod_bar中得到ImportError: cannot import name(关键的是,有些但不是全部)。如果我只运行mod_bar,导入工作正常,如果我删除依赖项并从mod_bar导入并从测试器运行它,它工作正常;只有当一个类的子集从f输入到b和t并且我从t运行时它才会中断。我已经尝试阅读关于导入如何工作以及谷歌搜索解决方案的文档,但我没有找到任何指向正确方向的东西。我有一种感觉这与Python内部的一些不起眼的部分有关,但我不知道那是什么。

我认为这准确地代表了正在发生的事情,尽管从testermod_bar的引用是间接的(tester是一个文件我涉及到一层额外的复杂性)当我处理它时,我会使用我的代码,而mod_bar实际上是Lettuce地形文件,而tester正在调用的其他模块正在加载Lettuce。)任何人都可以提供给我至少有一些地方开始寻找有关如何解决这个问题的信息?

编辑:

我正在看这个,特别是堆栈跟踪:

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__()是否会导致导致我头痛的循环导入?

1 个答案:

答案 0 :(得分:0)

所以是的,我正在进行循环导入。问题是,当你import lettuce时,lub.py会执行,然后动态导入terrain

我发生的事情是我有一个Session类导入AbstractSession,后者又导入LoggerManager,后者包含一个logging.Handler子类,它将日志消息推送到world中的队列,因此logger_manager会import lettuce访问world。我还希望我的所有测试都是通过旋转一个Session对象开始的,所以我在terrain中有一个@beforeeach方法在每次测试之前启动一个Session,这意味着在地形中导入Session。

当然,这意味着每次我在任何地方的任何文件中导入Session时,它都会触发整个事件链(会话&gt; AbstractSession&gt;莴苣&gt; terrain&gt;会话),使session.session.Session未初始化当地形试图加载它时。

我认为我最好的解决方法是坚持与地形中的世界相关联的日志处理程序和日志缓存,然后让地形附加处理程序本身。幸运的是,这是一个选项,因为日志记录是全局访问。这实际上有点改善了我的框架的划分,因为在核心库中没有任何关于生菜的代码,这些代码都将在生菜库中关闭。莴苣仍然没有内置这些​​地雷......

tl;博士,如果你想尝试做更多的事情而不是真正基本的测试套件,请避免生菜。