如何使用相对导入 运行 包内的模块?

How to run a module inside a package, using relative imports?

这个问题是针对 PyDev 的。包结构如下所示:

app
├── __init__.py
├── sub1
│   ├── __init__.py
│   └── mod1.py
└── sub2
    ├── __init__.py
    └── mod2.py

mod1.py模块:

from __future__ import print_function

def f():
    print('It works!')

mod2.py模块:

from __future__ import absolute_import
from ..sub1 import mod1

if __name__ == '__main__':
    mod1.f()

shell 中的一切都运行良好,python -m app.sub2.mod2 命令打印:

It works!

不出所料,一切都很好。 (from __future__ import absolute_import 行似乎没有效果:我可以将其注释掉,一切仍然正常。)

如果我在 PyDev IDE 中单击 mod2 并尝试 Run As > Python Run,我会得到

ValueError: Attempted relative import in non-package

这并不奇怪,因为默认情况下 -m 开关没有打开。如果我编辑 mod2 的 Run/Debug 设置:Arguments > VM Arguments 并在此处添加 -m-m 最有可能传递给 python 解释器,但现在我得到:

/usr/bin/python: Import by filename is not supported.

from __future__ import absolute_import行好像没有效果;我是否评论它并不重要;我正在使用 Python 2.7.

我现在没主意了。


开发者亲自确认在PyDev中还做不到;我已经为它开票了

Running a module inside a package, using relative imports


更新:截至 2016 年 12 月 2 日,问题已解决,请参阅已接受的答案。

编辑:

PyDev 5.4.0 中,现在有一个选项 运行 使用 -m 标志(这将通过其常规名称导入模块,而不是像 __main__这样相关的导入就可以在那里工作了)。

您可以在以下位置启用它:Preferences > PyDev > Run(即:这将为所有 运行 启用它——也许将来会有一个选项让每个 运行,但目前它是为所有发布全局设置的)。


原回答:

问题是您在主模块中有相对导入,PyDev 使用 python path/to/file_to_execute.py 而不是 python -m my.module 执行文件。

一个简单的修复是做一个单独的主模块,它依次从该模块导入一个 main() 函数并 运行s 它(尽管再次:它不能在模块中执行相对导入作为__main__(发生这种情况是因为该模块被称为 __main__,因此无法解析相对导入,因为它实际上没有使用可用于解析相对导入的名称导入)。

另一个修复方法是更改​​启动配置以在 VM 参数中添加 '-m my.module'(转到 运行 > 运行 配置来执行此操作——但您必须这样做对于您想要 运行 的每个主要模块,包括单元测试)。

最后的修复是更改 PyDev 本身(因此,请在 PyDev 跟踪器中为此创建一个票证:https://www.brainwy.com/tracker/PyDev/——或提交一个拉取请求,这将使添加该功能更快; ))