【发布时间】:2015-09-13 19:17:14
【问题描述】:
在我的一个项目中建立一个工作结构时,我有点挣扎。问题是,我在这样的结构中有主包和子包(我省略了所有不必要的文件):
code.py
mypackage/__init__.py
mypackage/work.py
mypackage/utils.py
utils.py 有一些通常只在 mypackage 包中使用的实用程序代码。
我通常每个模块文件都有一些测试代码,它调用当前模块的一些方法并打印一些东西来快速检查一切是否正常。此代码位于文件末尾的if __name__ == "__main__" 块中。所以我直接通过import utils 包含了utils.py。例如 mypackage/work.py 看起来像:
import utils
def someMethod():
pass
if __name__ == "__main__":
print(someMethod())
但是现在当我在父包(例如code.py)中使用这个模块并像这样导入它时
import mypackage.work
我收到以下错误:
ImportError: No module named 'utils'
经过一番研究,我发现可以通过将mypackage/ 文件夹添加到 PYTHONPATH 环境变量来解决此问题,但这对我来说感觉很奇怪。没有其他方法可以解决这个问题吗?我听说过相对进口,但python docs about modules 中提到了这一点
请注意,相对导入基于当前模块的名称。由于主模块的名称始终为“main”,因此用作 Python 应用程序主模块的模块必须始终使用绝对导入。
有什么建议可以让我在子模块中有一个if __name__ == "__main__" 部分,并且还可以使用父包中的这个文件而不会弄乱导入?
编辑:如果我在 work.py 中使用相对导入,如导入实用程序的答案中所建议的那样:
from . import utils
我收到以下错误:
SystemError: Parent module '' not loaded, cannot perform relative import
【问题讨论】:
-
当他尝试运行模块时,这将导致“尝试在非包中进行相对导入”。
-
@flammi88 你能描述一下你是如何运行它的以及从哪个文件夹运行它吗?
-
@sureshvv:我正在从文件所在的目录运行模块。例如,mypackage 目录中的 work.py 和父目录中的 code.py。
-
@flammi88:查看我的更新答案。我能够复制您的情况并在 python2 和 3 下成功运行它。
标签: python python-3.x