【问题标题】:Can't Import Module无法导入模块
【发布时间】:2012-11-06 20:23:18
【问题描述】:

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

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

是的,Geneticsys.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 时,一切似乎都可以正常导入。

为什么会出现此错误?这是循环进口的问题吗?我该如何解决这个问题?

【问题讨论】:

  • 您需要有一个__init__.py 文件才能正常工作。您的路径上是否有一个名为 Genetic.py 的文件?它可能没有导入您认为它正在导入的内容。
  • 那里 /is/ 一个 __init__.py 我将它从我的帖子的目录列表中排除,因为我认为它无关紧要。帖子编辑

标签: python eclipse python-2.7 pydev


【解决方案1】:

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

问题

问题是当你的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 的内容,这是需要避免的。

【讨论】:

  • 你一直做得很好,直到你选择了选项 b,这根本不起作用。当你引用一个模块的内容时,Python 并不关心:导入它的事实意味着它必须被解析,这导致了循环依赖。然而,将 import 移动到 __init__ 函数中是一个潜在的解决方案。
  • @DanielRoseman:确实必须解析模块,但这并不意味着所有对象都必须完全可用。你说的对from ... import ...来说是对的,但是当你使用裸import foo时,只要可以正确解析导入的模块,只要不尝试访问变量,就可以使用循环导入从它直到加载模块之后,它都会好起来的。关键是在上面 B 的第二个例子中,访问Foo.bar 的代码在模块导入时没有被执行。
  • @BrenBarn 做到了。问题不是在导入发生时出现,而是在导入模块尝试 access 导入模块中的某些内容时出现。如果您可以避免此类访问(这必然包括避免from ... import ... 格式导入),那么它将起作用。
  • 有没有一种方法可以导入所有内容(比如在__init__.py 中调用导入),以便我可以从各个模块本身中删除导入语句?
猜你喜欢
  • 2017-11-11
  • 2021-07-27
  • 2019-06-13
  • 2020-12-15
  • 2020-08-28
  • 2015-10-04
  • 2021-06-06
  • 2014-02-19
相关资源
最近更新 更多