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

こ雲淡風輕ζ 提交于 2020-01-15 09:08:02

问题


This question is specific to PyDev. The package structure looks like this:

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

The mod1.py module:

from __future__ import print_function

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

The mod2.py module:

from __future__ import absolute_import
from ..sub1 import mod1

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

Everything works beautifully from the shell, the python -m app.sub2.mod2 command prints:

It works!

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.)

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

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.

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.

I am out of ideas at this point.

  • In PyDev, how can I run a module inside a package that uses relative imports?

  • 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.)


The developer in person confirmed that it is not possible in PyDev yet; I have opened a ticket for it.

Running a module inside a package, using relative imports


UPDATE: As of Dec 2, 2016, the issue is resolved, see the accepted answer.


回答1:


Edit:

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).

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).


Original answer:

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.

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).

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).

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 ;) )



来源:https://stackoverflow.com/questions/31904307/how-to-run-a-module-inside-a-package-using-relative-imports

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!