So I am working on implementing a file structure to my Python and am having an error with doing imports. The file structure looks something like this:
Dirs(Folder)
╘ run.py
Vers(Folder)
╘ __init__.py
1_1(Folder)
╘ Main.py
secondary.py
__init__.py
1_2(Folder)
╘ Main.py
secondary.py
__init__.py
This is the contents of run.py
import importlib
print("This is the main module")
A = importlib.import_module(str("Vers.1_1.Main"))
A.start()
B = importlib.import_module(str("Vers.1_2.Main"))
B.start()
Each Main.py and secondary.py contain code that is the same except for the version number in the print statements, which is changed depending on the version number of the folder they are in.
Main.py
import secondary
class start():
def __init__(self):
print("This is version 1.2 main")
secondary.start()
secondary.py
class start():
def __init__(self):
print("This is version 1.1 secondary")
This is the output I get when I execute run.py
This is the main module
Traceback (most recent call last):
File "Python\Python36-32\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 978, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "Dirs\Vers1円_1\Main.py", line 1, in <module>
import secondary
ModuleNotFoundError: No module named 'secondary'
So from my understanding, run.py is able to successfully find and attempt to import Main.py from the 1_1 Folder. However, when executing the Main.py file, it is unable to see that secondary.py is in the same directory to import it. I've tried looking for how to fix this problem, but I really don't know what my issue is. Is how I am attempting to set up packages wrong? If so what do I need to change in order to make it work properly?
2 Answers 2
Short answer: Use
from . import secondary
Longer version: It looks like you assume Python 2 relative import semantics, when this is Python 3 with absolute import semantics. Have a look e.g. here for a more detailed explanation.
If you do
import secondary
this is an absolute import, and thus is not resolved relative to the current package, but rather from sys.path.
When you execute run.py as a Python script (not as a module with -m), the directory the script resides in gets added to sys.path automatically, which is why importing Vers.1_1.Main works, but import secondary does not.
4 Comments
from Mod import ClassA. How would I change that to the from . import notation? Does from . import Mod.ClassA work?from .Mod import ClassA. from ... import only allows you to import submodules directly, not as submodules (unless the outer module does that for you).After the import your code is executing under Dirs, where there is no secondary module to import
Change
import secondary
in Main.py
to
import Vers.1_1.secondary
and to
import Vers.1_2.secondary
in the other Main.py