This is very tricky in Python.
I'll first comment on why you're having that problem and then I will mention two possible solutions.
What's going on?
You must take this paragraph from the Python documentation into consideration:
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.
And also the following 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.
Relative imports work from the filename (__name__
attribute), which can take two values:
- It's the filename, preceded by the folder strucutre, separated by dots.
For eg:
package.test_A.test
Here Python knows the parent directories: before test
comes test_A
and then package
.
So you can use the dot notation for relative import.
# package.test_A/test.py
from ..A import foo
You can then have like a root file in the root directory which calls test.py
:
# root.py
from package.test_A import test
- When you run the module (
test.py
) directly, it becomes the entry point to the program , so __name__
== __main__
. The filename has no indication of the directory structure, so Python doesn't know how to go up in the directory. For Python, test.py
becomes the top-level script, there is nothing above it. That's why you cannot use relative import.
Possible Solutions
A) One way to solve this is to have a root file (in the root directory) which calls the modules/packages, like this:
root.py
imports test.py
. (entry point, __name__ == __main__
).
test.py
(relative) imports foo.py
.
foo.py
says the module has been imported.
The output is:
package.A.foo has been imported
Module's name is: package.test_A.test
B) If you want to execute the code as a module and not as a top-level script, you can try this from the command line:
python -m package.test_A.test
Any suggestions are welcomed.
You should also check: Relative imports for the billionth time , specially BrenBarn's answer.