【问题标题】:Python Relative Import cannot find packagePython 相对导入找不到包
【发布时间】:2016-12-03 09:13:06
【问题描述】:

我确信这是一个非常简单的问题,而且我只是遗漏了一些非常明显的东西,但这个困境的答案已经让我想了好几个小时。

我的项目目录结构如下:

-PhysicsMaterial
   -Macros
      __init__.py
      Macros.py
   -Modules
      __init__.py
      AvgAccel.py
      AvgVelocity.py
   -UnitTests
      __init__.py
      AvgAccelUnitTest.py
      AvgVelocityUnitTest.py
    __init__.py

除了对我的命名约定和目录结构的批评外,我似乎无法使用相对导入。我正在尝试相对导入要在 AvgAccelUnitTest.py 中测试的模块文件:

from .Modules import AvgAccel as accel

但是,我不断得到:

ValueError: Attempted relative import in non-package

由于我在整个结构中都设置了所有 init 文件,并且我还将顶级目录添加到了 PYTHONPATH,所以我很难过。为什么python没有正确解释包和导入文件?

【问题讨论】:

    标签: python package directory-structure relative-import


    【解决方案1】:

    这是因为您以__main__ 身份运行脚本。当你运行这样的脚本时:

    python /path/to/package/module.py
    

    该文件加载为__main__,而不是package.module,因此它不能进行相对导入,因为它不是包的一部分。

    这可能会导致奇怪的错误,即脚本中定义的类被定义两次,一次为__main__.Class,另一次为package.module.Class,这可能导致isinstance 检查失败和类似的奇怪现象。因此,您通常不应该直接运行您的模块。

    对于您的测试,您可以删除测试目录中的__init__.py,而只使用绝对而不是相对导入。事实上,您的测试可能根本不应该在您的包中。

    或者,您可以创建一个测试运行器脚本来导入您的测试并运行它们。

    【讨论】:

    • @Brendan Abel 感谢您提供的信息。在做了更多研究之后,我得出了完全相同的结论:最终,我最终使用了 sys.path.append 并执行了绝对导入。它不应该进一步打扰我,因为我不打算在目录中重新定位模块。这实际上也解决了另一个涉及我需要的函数装饰器的导入问题,所以这是两个大拇指!
    • 如果其他模块导入您在命令行上运行的相同模块,您可能仍然会遇到问题。
    • 我想当我走到那座桥时我会越过它。我敢肯定,到那时,我会有更好的解决方案。这只是一个爱好计划,几乎没有发布的意图,所以我认为结果会好的
    【解决方案2】:

    How to fix "Attempted relative import in non-package" even with __init__.py

    好吧,猜猜现在该使用 sys.path.append 了。为@BrenBarn、@fireant 和@Ignacio Vazquez-Abrams 鼓掌

    【讨论】:

      猜你喜欢
      • 2012-04-20
      • 1970-01-01
      • 2022-06-15
      • 1970-01-01
      • 2021-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多