如何使用相对导入在包内运行模块? [英] 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
行似乎没有效果:我可以将其注释掉,一切仍然正常.)
as expected, all is fine. (The from __future__ import absolute_import
line seems to have no effect: I can comment it out and everything still works just fine.)
如果我在 PyDev IDE 中单击 mod2
并尝试 Run As
> Python Run
,我得到 p>
If I click on mod2
in the PyDev IDE and try to Run As
> Python Run
, I get
ValueError: Attempted relative import in non-package
这并不奇怪,因为 -m
开关默认没有打开.如果我编辑 mod2
的运行/调试设置: Arguments > VM Arguments 并在此处添加 -m
;-m
最有可能传递给 python 解释器,但现在我得到:
which is not surprising as the -m
switch is not turned on by default. If I edit the Run/Debug settings for mod2
: Arguments > VM Arguments and add -m
here; the -m
is most likely passed to the python interpreter but now I get:
/usr/bin/python: Import by filename is not supported.
from __future__ import absolute_import
行似乎没有效果;我是否将其注释掉并不重要;我使用的是 Python 2.7.
The from __future__ import absolute_import
line seems to have no effect; it does not matter whether I comment it out or not; I am using Python 2.7.
我现在没有想法.
在 PyDev 中,如何在使用相对进口?
In PyDev, how can I run a module inside a package that uses relative imports?
我应该如何更改设置一次(全局),以便每当我尝试在包内运行一个模块,PyDev 做正确的事吗?(也就是说,我不必为每个单独指定设置我希望运行的模块.)
How should I change the settings once (globally) such that whenever I try to run a module inside a package, PyDev does the right thing? (That is, I don't have to individually specify the settings for each module that I wish to run.)
开发者亲自确认在PyDev中目前还无法实现;我已经为它开了一张票.
The developer in person confirmed that it is not possible in PyDev yet; I have opened a ticket for it.
更新:截至 2016 年 12 月 2 日,问题已解决,请参阅已接受的答案.
UPDATE: As of Dec 2, 2016, the issue is resolved, see the accepted answer.
推荐答案
在 PyDev 5.4.0
中,现在有一个使用 -m
标志运行的选项(它将通过其常规名称导入模块,而不是像以前那样__main__
这样相对导入就可以在那里工作).
In PyDev 5.4.0
, there's now an option to run using the -m
flag (which will import the module through its regular name and not as it was __main__
so that relative imports will work there).
您可以在以下位置启用它:Preferences >PyDev >运行
(即:这将为所有运行启用它——也许将来会有一个选项可以每次运行都启用它,但现在它为所有启动设置了全局).
You can enable it at: Preferences > PyDev > Run
(i.e.: this will enable it for all runs -- maybe in the future there'll be an option to make it per run, but for now it's set globally for all launches).
原答案:
问题是您的主模块中有相对导入,PyDev 使用 python path/to/file_to_execute.py
而不是 python -m my.module
执行文件>.
The problem is that you have relative imports in your main module and PyDev executes the file with python path/to/file_to_execute.py
instead of python -m my.module
.
一个简单的修复是做一个单独的主模块,然后从该模块导入一个 main() 函数并运行它(尽管再次:它不能在模块中以 __main__
(发生这种情况是因为模块名为 __main__
,因此无法解析相对导入,因为它实际上并未使用可用于解析相对导入的名称导入).
A simple fix is doing a separate main module which in turn imports a main() function from that module and runs it (although again: it can't have relative imports in the module executed as __main__
(this happens because the module is called __main__
and thus cannot resolve a relative import because it wasn't actually imported with a name which can be used to resolve the relative import).
另一个修复是更改启动配置以在 VM 参数中添加 '-m my.module'
(转到运行 > 运行配置来执行此操作 - 但您必须这样做对于您要运行的每个主要模块,包括单元测试).
Another fix would be changing the launch configuration to add the '-m my.module'
in the VM arguments (go to run > run configurations to do that -- but you have to do that for each main module you want to run, including unit-tests).
最后一个修复是更改 PyDev 本身(因此,请在 PyDev 跟踪器中为此创建一个票证:https://www.brainwy.com/tracker/PyDev/ -- 或提交拉取请求,这样可以更快地添加该功能;) )
And the last fix would be changing PyDev itself (so, please create a ticket for that in the PyDev tracker: https://www.brainwy.com/tracker/PyDev/ -- or submit a pull request, which would make adding that feature much faster ;) )
这篇关于如何使用相对导入在包内运行模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!