无法导入模块

时间:2012-11-18 21:39:32

标签: python eclipse python-2.7 pydev

首先,这很可能不是路径问题。

我在eclipse中有一个pydev项目。这是目录结构:

Genetic-Framework
  | Genetic-Framework
    | Genetic
      | __init__.py
      | GA.py
      | crossover.py
      | fitness.py
      | individual.py
      | mutation.py
      | population.py
      | selection.py
      | settings.py
      | visualization.py

GA.py中,我有以下一行:

from Genetic import settings, selection, visualization as vis

是的,Genetic位于sys.path。但是,我收到以下错误:

  File "/.../Genetic-Framework/Genetic-Framework/Genetic/GA.py", line 17, in <module>
    from Genetic import settings, selection, visualization as vis
ImportError: cannot import name settings

但是,当我从该行中删除settings时,其他所有内容都会正常导入。

有趣的是,settings.py的第一行是:

from Genetic import fitness, selection, mutation, crossover, population, GA

当我从该行中删除GA时,一切似乎都很正常。

为什么我收到此错误?这是循环进口的一些问题吗?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:4)

是的,这是循环导入的问题。

问题

问题是,当您运行GA.py时,它会首先尝试导入settings。这意味着settings.py开始运行,并立即尝试导入GA

但是,GA已在加载过程中,因此GA.py无法再次运行 - 相反,settings只会加载GA已经在内存中(目前大部分都是空的,因为它仍在执行其导入)。

因此,尝试使用settings中的内容的GA中的内容失败,因为他们在GA中寻找的内容尚未定义(因为处理GA.py尚未完成进口。)

这使得settings.py的评估引发了异常,表现为导入失败(因为导入期间引发的异常导致导入失败)。

解决方案

a)首先避免这种情况。

一般情况下,您应该首先尝试避免循环导入。它们通常意味着你有很奇怪的依赖结构,以后很难调试。

这样做的一种方法是尝试找到两个模块中所需的东西,然后将它们分成另一个可以在另外两个模块之间共享的第三个模块 - 所以不要在B中使用Ax,而在A中使用By ,你改为在A和B中使用Cx和Cy。

b)在加载所有内容之前,实际上不要尝试使用循环导入的东西。

您可以做的另一件事是在所有导入完成之后推迟使用其他模块中的某些内容。换句话说,不要尝试从顶级代码引用导入模块的内容,而是将其放在类初始值设定项或稍后可以调用的函数中,一旦所有导入完成。

例如,而不是......

import Foo

class Baz:
    top_level_variable = Foo.bar

你可以这样做:

import Foo

class Baz:
    def __init__(self):
        self.instance_variable = Foo.bar

显然,实例属性与类属性略有不同,但其目的是推迟实际上必须从其他模块查找内容,直到所有模块完成执行并因此使其内容可用。另请注意,此处from Foo import bar将失败,因为它会在导入时尝试访问Foo的内容,这是需要避免的。