如何在 python 3.6 中使用绝对和相对导入?

How do I use absolute and relative imports in python 3.6?

我有一个名为 "slingshot" 的 python project/library,其目录结构如下:

slingshot/
    __init__.py
    __main__.py
    build.py
    deploy.py
    util/
        __init__.py
        prepare_env.py
        cdn_api.py

来自 __main__.py 我想从 util/prepare_env.py.

导入函数

我想确保 util 指的是我项目中的 util,而不是可能安装在某处的其他 util 库。

我尝试了 from .util import prepare_env,但出现错误。

from util import prepare_env 似乎有效,但没有解决 "util".

的歧义

我做错了什么?


__main__.py如下:

import os
from .util import prepare_env

if __name__ == '__main__':
    if 'SLINGSHOT_INITIALIZED' not in os.environ:
        prepare_env.pip_install_requirements()
        prepare_env.stub_travis()
        prepare_env.align_branches()
        os.environ['SLINGSHOT_INITIALIZED'] = 'true'

当我键入 python3 ./slingshot 时,出现以下错误:

  File "./slingshot/__main__.py", line 2, in <module>
    from .util import prepare_env
ImportError: attempted relative import with no known parent package

当我键入 python3 -m ./slingshot 时,出现以下错误:

/usr/local/opt/python3/bin/python3.6: Relative module names not supported
当您使用 -m 命令行开关时,包中的

__main__.py 模块将模块 运行 作为脚本。该开关采用 模块名称 ,而不是路径,因此删除 ./ 前缀:

python3 -m slingshot

当前工作目录被添加到模块搜索路径的开头,因此首先找到 slingshot,此处无需指定相对路径。

来自-m switch documentation:

Search sys.path for the named module and execute its contents as the __main__ module.

Since the argument is a module name, you must not give a file extension (.py). The module name should be a valid absolute Python module name[.]

[...]

As with the -c option, the current directory will be added to the start of sys.path.