首先,这很可能不是路径问题。
我在 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
时,一切似乎都导入得很好。
为什么我会收到此错误?这是循环导入的问题吗?我该如何解决这个问题?
最佳答案
是的,这是循环导入的问题。
问题
问题是当你的 GA.py
运行时,它首先尝试导入 settings
。这意味着settings.py
开始运行,它立即尝试导入 GA
.
但是,GA
已经在加载过程中,所以GA.py
不会第二次运行 - 相反,settings
只需加载 GA
它已经在内存中(目前大部分是空的,因为它仍在执行其导入)。
因此,settings
中的内容尝试使用 GA
中的东西失败,因为他们在 GA
中寻找的东西尚未定义(因为 GA.py
的处理尚未通过导入)。
这使得settings.py
的评估引发异常,表现为导入失败(因为导入过程中引发异常导致导入失败)。
解决方案
a) 首先避免出现这种情况。
一般来说,您应该首先尝试避免循环导入。它们通常意味着您有非常奇怪的依赖结构,以后很难调试。
实现此目的的一种方法是尝试找到两个模块中所需的内容,并将它们分解为可以在其他两个模块之间共享的单独的第三个模块 - 因此不要在 B 中使用 A.x,在 A 中使用 B.y ,您可以在 A 和 B 中使用 C.x 和 C.y。
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
的内容在导入时,这是需要避免的。
关于python - 无法导入模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13444900/