I've come across various ways to include files from other directories in python. At this time, none of my python projects have ever scaled enough to warrant a nice directory structure but I find this information useful to know.
The Python Docs 6.1.4 explain nicely what happens when you try to import a module.
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
- The directory containing the input script (or the current directory when no file is specified).
- PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
- The installation-dependent default.
Python searches various specific locations for the moduled named. Those locations are determined by the contents of sys.path.
Since Python will search sys.path when it reaches an import module
instruction, we can include the path to that module in sys.path before calling the import. Given a folder structure like this
Main/
Main.py
Tanks/
Tank.py
we can import Tank.py like this
import sys
sys.path.append("./Tanks")
import Tank
This method is inspired by Section 6.4 of the Python docs. It states that the presence of an __init__.py
file (may be empty) will cause python to treat the directory it is in as a Package
. That means we will be able to import <directory>
as a module.
Notice that one of the directories in sys.path by default is the directory that the python file launched from. We can use that information to interpret the line When importing the package, Python searches through the directories on sys.path looking for the package subdirectory.
Thus, any folders with __init__.py
under a directory in sys.path will be importable as a module. So, given
Main/
Main.py
Tanks/
__init__.py
Tank.py
BlueTanks/
__init__.py
BlueTank.py
We can import Tank.py like <Directory(a.k.a "package")>.filename
import Tanks.Tank
And we can continue this pattern
import Tanks.BlueTanks.BlueTank
thanks for the short and to the point explanation!