【问题标题】:How to import two submodules in python with the same subfolder name如何在python中导入具有相同子文件夹名称的两个子模块
【发布时间】:2019-10-29 13:04:28
【问题描述】:

我的项目结构如下:

project/
  main.py
  sub_a/
    class_a.py
    __init__.py
    utils/
      __init__.py
      util_a.py
  sub_b/
    class_b.py
    __init__.py
    utils/
      __init__.py
      util_b.py

在每个class_a.py、class_b.py 中,都有这样的导入:

from utils import util_a/b

我的PYTHONPATH 指向sub_a 和sub_b。当我尝试

import class_b

在 main.py 中,我收到 ImportError:

ImportError: cannot import name util_b

我使用的是 Python 2.7。

我知道错误的出现是因为from utils import util_b 不明确,因此 Python 选择路径上的第一个,但我怎样才能重写导入以使其工作?

我不认为更改PYTHONPATH 是一种选择,因为sub_a 和sub_b 中的每一个都假设它们是PYTHONPATH 在自己的内部导入中的一部分。比如class_b.py中的from utils import util_b。

【问题讨论】:

  • 有问题的导入语句在哪里?是在main.py 里面吗?我开始在回购中玩这个:github.com/fireproofsocks/python_import。 -- 这是一项正在进行的工作,但其中的一个示例可能有助于阐明 Python 的行为。

标签: python python-import


【解决方案1】:

不要将两个子目录都添加到PYTHONPATH。相反,只添加project 并导入sub_a.utils.util_a 和sub_b.utils.utils_b。
(在包本身中,您可以使用relative imports 从同一子树中导入内容。例如在sub_b/__init__.py:import .utils.utils_b)

根据 isinstance fails for a type imported via package and from the same module directly ,如果您添加子目录,utils 包将与 sys.path 上的较早者相关联,并且只有在您尝试从 utils 导入任何内容时才会搜索它。

【讨论】:

  • 我不认为这很有效,因为每个子模块都依赖于自己的导入。例如,sub_b 中的文件调用类似于 from utils import util_b。
  • @mwlon 在这种情况下使用相对导入:from .utils import util_b。
  • 那么如果不更改其中一个或两个子模块,就没有办法让它工作吗?另外,相对进口不是不赞成吗?
  • @mwlon 相对导入是语法糖。 sub_b 中的 from .utils import util_b 等价于 from sub_b.utils import util_b,但没有硬编码当前模块名称。当它们是新的时,它们可能不受欢迎,但现在所有非 EOL 版本都支持它们。有关利弊,请参阅realpython.com/absolute-vs-relative-python-imports。
【解决方案2】:

您要查找的是“导入为”

这里有很好的概述: 在另一个线程中回答from ... import OR import ... as for modules'

从 project.sub_a 导入用户作为用户

从 project.sub_b 导入用户为 bUser

【讨论】:

  • 我澄清了每个子模块需要自己的 pythonpath 才能从 utils 导入的约束,这变得模棱两可。我该如何解决这个问题?
猜你喜欢
  • 1970-01-01
  • 2012-01-31
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
  • 2011-06-23
  • 2020-01-26
  • 1970-01-01
  • 2020-03-02
相关资源
最近更新 更多