0

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

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

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

编辑:

我正在查看更多内容,特别是堆栈跟踪:

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__()循环进口让我感到头疼?

4

1 回答 1

0

所以是的,我得到了一个循环导入。问题是,当你import lettuce执行 lettuce.py 时,它会动态导入terrain.

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

当然,这意味着每次我在任何地方的任何文件中导入 Session 时,都会触发整个事件链(Session>AbstractSession>lettuce>terrain>Session),从而在地形尝试加载时使 session.session.Session 未初始化它了。

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

tl;博士,如果您想尝试做的不仅仅是真正的基本测试套件,请避免使用生菜。

于 2012-04-30T21:26:04.827 回答