CDSW 的相对进口

relative imports on CDSW

我有一个关于 CDSW 的项目,组织如下:

/home/cdsw/my_project_v2.1
   |_>input
   |_>output
   |_>scr
      |_>__init__.py
      |_>main.py
      |_>utils
          |_>__init__.py
          |_>helpers.py

在我当前的代码中,我使用 sys.path.append 来执行导入。

import sys

sys.path.append("/home/cdsw/my_project_v2.1/src/utils/")

from helpers import bar

这很好用,但这是一种不好的做法,因为如果版本发生变化,那么我需要更改所有使用该路径的脚本。

我想用一些相对路径替换它:

from .utils.helpers import bar

但是我得到了错误:

$ pwd
/home/cdsw
$ python3 my_project_v2.1/src/main.py 
Traceback (most recent call last):
  File "my_project_v2.1/src/main.py", line 1, in <module>
    from .utils.helpers import bar
ModuleNotFoundError: No module named '__main__.helpers'; '__main__' is not a package

我需要在我的体系结构或代码中更改什么才能使其正常工作?

只需使用

from utils.helpers import bar

Python 命令行参数的 documentation 的简短摘录:

If the script name refers directly to a Python file, the directory containing that file is added to the start of sys.path, and the file is executed as the __main__ module.

这句话的前半部分表示在引用目录内容时可以使用绝对模块名称,因为Python 会在那里搜索模块。不能使用相对导入是后半句的结果。

作为旁注,您还可以考虑从目录名称中省略版本号,或者更好的是,将您的代码直接放在 /home/cdsw 中。后者听起来可能很奇怪,因为您永远不会在常规机器上这样做,但这里的所有内容都在一个容器中,实际上这就是您的代码应该在 CDSW 中组织的方式。您可以通过基于模板或 git URL 创建一个新项目来确认这一点——两者都会将代码直接放在主目录中。