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.