【问题标题】:Python imports in nested structure嵌套结构中的 Python 导入
【发布时间】:2021-05-21 11:50:26
【问题描述】:

有如下结构:

project/
   I-----main.py
   I-----src/
          I----__init__.py (empty)
          I----util.py
          I----shared/
                  I----__init__.py (empty)
                  I----hello.py 


#main.py
from src import util

#util.py (runs without errors)
from shared import hello

#hello.py (runs without errors)
def hello():
    print("Hello")

我尝试运行 main.py,得到结果

ModuleNotFoundError: 没有名为“共享”的模块

如何修复 main.py 中的导入?

【问题讨论】:

  • 为什么有两个__init__.pys?请查看stackoverflow.com/questions/2164258/…
  • @newQOpenGLWidget 每个包一个 __init__.py,这对我来说是正确的。 __init__.py 不是构造函数。

标签: python python-3.x python-import


【解决方案1】:

你可能想from src.shared import hello

【讨论】:

  • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
  • @mufazmi:这个确实提供了答案。也就是说,subsequently contributed answers 重申了这个建议,但提供了更多细节。
  • 它不是一个稳定且始终有效的解决方案
【解决方案2】:

此类失败有两个主要原因:

  1. 模块导入:您没有正确导入模块。您可以使用模块的__init__.py 通过提及其子模块的导入来导入它,也可以通过导入直接放置完整路径。例如,您可以使用from src.shared import hello。或者,在您的__init__.py 文件中,在src 模块中,您可以添加from shared import hello。这也将起作用,因为每当您导入模块时,在该模块中运行的第一件事就是该文件的 __init__.py。

  2. 循环导入:这不是你的情况,但我提出这个问题是因为很多时候我们忽略了这一点并陷入困境。当两个模块相互依赖时,就会发生循环导入。我已经在帖子What is Circular Import and how to avoid it 中描述了它发生的原因以及如何避免它。

【讨论】:

    【解决方案3】:

    我找到了可能的解决方案(效果很好):

    
        #util.py
        import sys
        from pathlib import Path
        
        root = Path(__file__).parent.parent #depends on file's place in general structure
        sys.path.append(str(root))
        import src.shared.hello as hello
    
    

    【讨论】:

      【解决方案4】:

      您需要使用相对导入:

      from .shared import hello
      

      如果你正常运行util.py,.../project/src 会附加到sys.path,Python 可以找到导入。但是,当您运行main.py 时,.../project/ 会附加到sys.path,Python 找不到shared 模块。通过使用相对导入,Python 查找相对于当前包的模块名称,并可以找到 shared 模块。

      另请参阅:Relative imports for the billionth time

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-30
        • 1970-01-01
        • 2013-08-07
        相关资源
        最近更新 更多