Explanation
Use Case: Reference a top-level <module_name>.py module from a low-level (subfolder) <script_name>.py
I was under the impression one could import python scripts and their respective variables into other scripts within a project directory as long as they all had a main directory in common.
.
└── spam/ Main directory (git repo)
├── spam/ Main project directory
│ ├── __init__.py
│ ├── ham/ Directory within main project spam/
│ │ ├── __init__.py
│ │ └── eggs.py Script within sub directory ham/
│ └── config.py Config with contents eggs.py needs
└── README.md
(Note: Yes, the main directory and the main project directory have the same name.)
For example, I thought the above structure would allow this behavior: use contents from config with eggs.py
#! /spam/spam/ham/eggs.py
from spam import config
Well, not quite...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'spam'
So I took one step back.
#! /spam/spam/ham/eggs.py
import spam
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'spam'
I was wrong.
I am not so much looking for a solution at this point (since I found a few different ones including here and here (though the explanations did not really get through my thick skull). Would anyone like to explain it to me like I'm a 5th grader?
I will continue to collect what I consider to be valuable resources for finding the answers to my question. I appreciate all contributions that help clear up this picture.
Ongoing Discoveries
Exploratory Testing
Imports work for the above image.
# ../spam
# Direct import statements.
import spam
import config
# Indirect to get ham.
import spam.ham
from spam import ham
# Indirect to get eggs.
import spam.ham.eggs
from spam.ham import eggs
Imports work for the above image.
# ../spam/spam
# Direct import statements.
import ham
# Indirect to get eggs.
import ham.eggs
from ham import eggs
Imports work for the above image.
# ../spam/spam/ham
# Direct import statements.
import eggs
Observations
- when doing
import <module_name>
, the current directory is checked but "backwards blind" - namespaces play a key role here
- relative imports are only for use within module files (i.e., not within interactive interpreters)
Resources for Better Understanding
- Stack Overflow "Relative imports for the billionth time " Answer by BrenBarn
- Stack Overflow Importing modules from parent folder Answer by np8*
*Solutions I test and find acceptable.
Tools and Versions
Python 3.8.6