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

时间:2015-08-09 12:38:15

标签: pydev

此问题特定于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的运行/调试设置:参数> VM Arguments并在此处添加-m; -m很可能传递给python解释器,但现在我得到了:

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

from __future__ import absolute_import行似乎没有效果;我是否评论出来并不重要;我使用的是Python 2.7。

我现在没有想法。

  • 在PyDev中,如何在使用relative的包中运行模块 进口?

  • 我应该如何(全局)更改设置,以便每当我 尝试在包内运行一个模块,PyDev做对了吗? (也就是说,我不必单独指定每个设置 我希望运行的模块。)

开发人员亲自确认在PyDev中不可能;我为它开了一张票。

Running a module inside a package, using relative imports

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

1 个答案:

答案 0 :(得分:3)

编辑:

PyDev 5.4.0中,现在可以选择使用-m标志运行(它会通过常规名称导入模块,而不是__main__,因此相对进口将在那里工作。)

你可以在Preferences > PyDev > Run启用它(即:这将启用所有运行 - 也许将来可以选择每次运行它,但现在它&#39 ; s为所有发布设置全局。)

原始答案:

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

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

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

最后一个修复程序将改变PyDev本身(所以,请在PyDev跟踪器中创建一个票证:https://www.brainwy.com/tracker/PyDev/ - 或提交一个拉取请求,这将使得更快地添加该功能;))