Import files from different folder in Python
Problem description
How to import Python scripts from files located in different folders?
Problem solution
Importing Python scripts depends on the directory structure we're working with. There are different methods for child, parent, or sibling directories.
In this example we have the following directory structure:
application
├── main.py
├── app
│ ├── folder
│ │ └── file.py
│ └── code.py
└── app2
└── file2.py
You should be able to import functions from any on of this files to any other.
Import from child directories
To import functions from code.py to main.py, you can use following code:
from app.code import *
You can use similar syntex to import functions from file2.py:
from app2.file2 import *
If you want to import from file.py, add subdirectory to your import path:
from app.folder.file import *
Import from parent or sibling directories
You can do it by two ways:
- with Package Relative Import
- by changing PYTHONPATH
With Package Relative Import
To import files from parent or sibling directories, you can use package relative imports. First, you have to creaty an empty file named __init__.py in each directory to make them recognized as packages by Python:
application
├── main.py
├── __init__.py
├── app
│ ├── folder
│ │ ├── file.py
│ │ └── __init__.py
│ ├── code.py
│ └── __init__.py
└── app2
├── file2.py
└── __init__.py
To import functions from main.py into file2.py, that is import from parent directory, you can use the following code:
from ..main import *
To avoid the following error:
ImportError: attempted relative import with no known parent package
You must call file2.py using -m (module) syntax. Run the following command from the parent directory of application:
python -m application.app2.file2
To import functions from code.py into file2.py, that is import from sibling directory, you can write following code in file2.py:
from ..app.code import *
REMEMBER You must use -m syntax to execute file2.py or execution will file, just like with imports from parents directories.
By changing PYTHONPATH
As you've seen, package relative imports can be quite fragile and may prevent us from running Python scripts in the usual way. But there is an alternative for importing files from parents or sibling directories, you can add the directory to the system path before importing it. This avoids the issues with relative imports.
To import main.py into file2.py, you can use this code:
import os, sys
sys.path.insert(1, "/".join(os.path.realpath(__file__).split("/")[0:-2]))
import main
Using this code, you created the path to main.py by taking the full path of file2.py and cutting of last two segments (app2/file2.py) from it. You insert it into the system path at index 1 to ensure it resolves after the main script but before any other paths. Now, you can import main.py or any other files in application using their names.
To import code.py into file2.py, that is import from sibling directory, you can write the following code:
import os, sys
sys.path.insert(1, "/".join(os.path.realpath(__file__).split("/")[0:-2]) + "/app")
import code
REMEMBER Changing the system path is convenient, but can cause problems if you files with same names in diffrent directiories.