2016-07-28 77 views
2

我敢肯定,这是一个非常简单的问题,我只是错过了一些非常明显的东西,但是现在这个困境的答案已经让我几个小时了。Python的相对导入找不到包

我的项目目录结构是这样的:一边在我的命名惯例,在这里目录结构

-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 

因为我有我的所有初始化文件设立的在我的整个结构中,我也将顶级目录添加到我的PYTHONPATH中,我很难过。为什么python不能解释包并正确导入文件?

回答

2

发生这种情况是因为您运行的脚本为__main__。当你运行一个这样的脚本:

python /path/to/package/module.py 

该文件被加载为__main__,而不是package.module,所以它不能做的相对进口,因为它不是一个包的一部分。

这可能会导致奇怪的错误,其中您的脚本中定义的类被定义两次,一次为__main__.Class,再次为package.module.Class,这可能导致isinstance检查失败并出现类似的异常情况。正因为如此,你通常不应该直接运行你的模块。

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

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

+0

@ Brendan Abel谢谢你的信息。在做了更多研究之后,我得出了完全相同的结论:最终,我最终使用了sys.path.append并执行绝对导入。它不应该进一步打扰我,因为我不打算在目录中重新定位模块。这实际上也解决了另一个涉及我需要的函数装饰器的导入问题,所以这是两个大拇指! –

+0

如果其他模块导入您在命令行上运行的相同模块,则可能仍会遇到问题。 –

+0

我想我会穿过那座桥。到那时我肯定会有更好的解决方案。这只是一个没有意图发货的业余爱好程序,所以我认为它会好起来的 –