Imagine this directory structure:
app/ __init__.py sub1/ __init__.py mod1.py sub2/ __init__.py mod2.py
I'm coding mod1
, and I need to import something from mod2
. How should I do it?
I tried from ..sub2 import mod2
but I'm getting an "Attempted relative import in non-package".
I googled around but found only "sys.path
manipulation" hacks. Isn't there a clean way?
Edit: all my __init__.py
's are currently empty
Edit2: I'm trying to do this because sub2 contains classes that are shared across sub packages (sub1
, subX
, etc.).
Edit3: The behaviour I'm looking for is the same as described in PEP 366 (thanks John B)
Relative imports use dot(.) notation to specify a location. Single dot specifies that the module is in the current directory, two dots indicate that module is in its parent directory of the current location and three dots indicate that it is in grandparent directory and so on.
Note that relative imports are based on the name of the current module. Since the name of the main module is always “main”, modules intended for use as the main module of a Python application must always use absolute imports.
Everyone seems to want to tell you what you should be doing rather than just answering the question.
The problem is that you're running the module as '__main__' by passing the mod1.py as an argument to the interpreter.
From PEP 328:
Relative imports use a module's __name__ attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to '__main__') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.
In Python 2.6, they're adding the ability to reference modules relative to the main module. PEP 366 describes the change.
Update: According to Nick Coghlan, the recommended alternative is to run the module inside the package using the -m switch.
Here is the solution which works for me:
I do the relative imports as from ..sub2 import mod2
and then, if I want to run mod1.py
then I go to the parent directory of app
and run the module using the python -m switch as python -m app.sub1.mod1
.
The real reason why this problem occurs with relative imports, is that relative imports works by taking the __name__
property of the module. If the module is being directly run, then __name__
is set to __main__
and it doesn't contain any information about package structure. And, thats why python complains about the relative import in non-package
error.
So, by using the -m switch you provide the package structure information to python, through which it can resolve the relative imports successfully.
I have encountered this problem many times while doing relative imports. And, after reading all the previous answers, I was still not able to figure out how to solve it, in a clean way, without needing to put boilerplate code in all files. (Though some of the comments were really helpful, thanks to @ncoghlan and @XiongChiamiov)
Hope this helps someone who is fighting with relative imports problem, because going through PEP is really not fun.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With