Python Import From a Parent Directory: A Quick Guide

by | Python

Ever found yourself knee-deep in Python files, struggling to import a module from a parent directory? If so, you’re in good company. Python’s import system can sometimes feel like a winding maze, but don’t worry, we’re here to help you navigate!

To import from a parent directory in Python, you can use the sys module. By inserting the required directory into the sys.path list, you provide the interpreter with the location of the desired module. After modifying the sys.path, you can import the target module using the standard import statement.

Python Import from a Parent Directory

In this article, we’ll explore how you can import from parent directories in Python. Furthermore, we’ll look at specific use cases of importing that will help you better understand the underlying structure of the directories.

Let’s get into it!

How to Import in Python

We’re going to jump straight into today’s topic: importing in Python. Those simple lines of code at the beginning of your Python scripts that often begin with import or from? Those are your ticket to tapping into the power of Python’s extensive libraries and modules.

In this section, we’ll go over the code for importing from parent directory in Python. We’ll also look at potential errors that can arise when importing modules from parent directory.

What is Python Import System?

The Python import system allows efficient code reuse and organization. It makes it easier for you to maintain complex projects.

To import a module or package in Python, you can use the import statement. Modules are distributed as packages, which are directories with a collection of Python files.

To import a module from the parent directory, you can use the sys.path module to add the parent directory to Python’s path. After adding the parent directory, you can import the module using the import statement.

Demonstration of Importing from Parent Directory

To give you a clear demonstration of importing from parent directory, let’s go over a series of steps to help you understand the entire process.

1. Creating the necessary directories and files

First, open your file explorer and navigate to your desired local drive. I’m using my local E drive, therefore, I’ll create a new directory named my_project.

Inside my_project, create another directory named module_dir.

So, you should now have:

E:
|-- /my_project
    |-- /module_dir

2. Adding Python files

Next, create a new .py file named main.py in my_project directory.

After that, create another Python file named my_module.py in module_dir.

Your structure should now look like this:

E:
|-- /my_project
    |-- main.py
    |-- /module_dir
        |-- my_module.py

If you’re using Visual Studio Code, your directory structure should look like the following:

Directory structure in VS Code

3. Editing the Python files

Open your my_module.py and add the following code:

def my_function():
    print("Hello from my_module!")

Then go ahead and save and close the file.

Now, open main.py and add the following code:

import sys
import os

# Get the parent directory
parent_dir = os.path.dirname(os.path.realpath(__file__))

# Add the parent directory to sys.path
sys.path.append(parent_dir)

# Import the module from the parent directory
from module_dir import my_module

# Use a function from my_module
my_module.my_function()

In this script, we’re first figuring out the location of the directory one level up from the script we’re running (that’s the parent directory). Then, we’re telling Python to also look in this parent folder when it needs to import modules.

After doing that, we’re importing a module named my_module that’s inside a directory called module_dir located in this parent directory. Finally, we’re calling a function named my_function from my_module.

After adding the above code, save and close the file.

4. Running the Code

To run this code, open your desired code editor’s terminal and run the main.py file. If you are using Visual Studio Code, the output should look like the following:

Running the main.py code in Python

The main.py will import the function from my_module.py, as shown in the image above.

This example shows in detail how file system and importing from parent directory works in Python.

How to Handle ImportError and ModuleNotFoundError in Python

Python will raise an ImportError exception when the module you are trying to import is not found during the importing process.

How to Handle ImportError and ModuleNotFoundError

ImportError is a subclass of the ModuleNotFoundError exception. It’s raised when the imported module doesn’t exist or can’t be loaded.

The following are examples of scenarios when these may occur:

  • The module or package is not in the sys.path.

  • The module or package name is misspelled or does not exist.

  • There is a problem with the module’s code, preventing it from being properly imported.

When encountering these errors, you could use the following solutions:

  • Double-checking the spelling and existence of the module or package.

  • Adding the necessary directory to sys.path using append() or insert().

  • Fixing any issues in the module’s code that may be hindering its import.

To learn more about handling errors in Python, check the following video out:

After understanding how importing works in Python, it’s also important that you gain some familiarity with Python’s directory structure.

Directory structure and importing go hand-in-hand with each other as importing requires an understanding of the directory structure, so let’s go over that in the next section.

Python Directory Structure

Understanding the Python directory structure is more than just knowing where to put your scripts or where to find that library you just installed.

It’s like having a clean, well-organized desk: you’ll know exactly where everything is, and your productivity will skyrocket, so let’s go over the basics in this section.

Package Structure

The directory structure of a Python project is essential for correct organization. If you structure your package properly, it’ll help you minimize the chance of naming conflicts. Furthermore, it’ll also enable you to easily navigate through your filesystem.

The following is a typical Python project directory structure:

project/
?
??? package1/
?   ??? __init__.py
?   ??? module1.py
?   ??? module2.py
?
??? package2/
?   ??? __init__.py
?   ??? module3.py
?   ??? module4.py
?
??? main.py

In the example above, project is the root directory containing two sub-packages, package1 and package2. Each package has its .py files and a unique init.py file.

What Are init.py Files?

init.py files are important for defining the package’s behavior when it’s imported. These files are executed when their parent package is imported.

The init.py files can be empty or contain initialization code. They also indicate to Python that the folder should be treated as a package.

To import a module from a parent directory, you can use the sys.path method. You’ll need to append the parent directory path to sys.path.

To demonstrate this, let’s build up on our previous example. We had the following directory structure:

E:
|-- /my_project
    |-- main.py
    |-- /module_dir
        |-- my_module.py

Now, let’s add the init.py file to my_module directory. You can leave this file empty for now. Its presence indicates to Python that this directory should be treated as a package.

Your directory structure should now look like the following:

Modified directory structure after adding init.py file

After adding the init.py file, you must make changes to your main.py file to instruct it to treat the module_dir folder as a package. Your main.py file should now have the following code:

import sys
import os

# Get the parent directory
parent_dir = os.path.dirname(os.path.realpath(__file__))

# Add the parent directory to sys.path
sys.path.append(parent_dir)

# Import my_module from the package module_dir
import module_dir

# Call my_function from my_module
my_module.my_function()

In this example, main.py imports the module_dir package, and then calls the function my_function() from my_module within that package.

Note the change in the call to the my_function; because we are now treating module_dir as a package, we have to include the package name when calling functions from modules within the package.

The output will be similar to the previous one. The only change we made was to treat module_dir as a package with the inclusion of init.py file.

Output of main.py

Python Search Path

Ever wondered how Python knows where to find the modules you’re trying to import? Or maybe you’ve encountered an annoying ‘ModuleNotFoundError’ and couldn’t figure out why?

In this section, we’re going to tackle these mysteries head-on and delve into the concept of the Python search path.

The Python search path, also known as sys.path, is Python’s little roadmap to finding all the modules you need. Like a diligent scout, Python uses this path to scour your computer for modules whenever you use the import statement.

Understanding how it works can save you from headaches and help you troubleshoot when things go awry, so let’s go over some basics!

1. What is the sys.path List in Python?

The sys.path list is a crucial component when importing modules in a directory. It’s a list of strings that represents the module search path.

Each string in the list is a directory location where Python looks for modules (*.py files) or packages (folders containing init.py files).

The following example shows you how to view your current sys.path list:

import sys

for path in sys.path:
    print(path)

After running the above code, you’ll see an output like the following:

Viewing the current sys.path list

You can also add new directories to the sys.path list so that Python finds your custom modules.

For instance:

import sys
sys.path.append('/path/to/new/module/directory')

2. What are PythonPath Environment Variables?

Another way you can manage the module search path is by using the PYTHONPATH environment variable.

PYTHON PATH is a string containing a list of directories that is appended to the default sys.path list. This means you can add directories to PYTHONPATH. This allows Python to search for modules in those directories when importing.

Setting the PYTHONPATH environment variable depends on your operating system:

  • Unix-based systems (Linux, macOS): You can use the export command in your terminal or add the following line to your shell configuration file (.bashrc, .zshrc or similar):

    export PYTHONPATH="/path/to/module/directory1:/path/to/module/directory2"
  • Windows OS: Go to System Properties > Environment Variables, and under User variables, click New to create a new variable with the name: “PYTHONPATH” and the value as a list of directory paths separated by a semi-colon (;).

    C:pathtomoduledirectory1;C:pathtomoduledirectory2
    

Once the path variable is set, you can run your Python script. It will search for imported modules in those directories as well as the default ones in sys.path.

When organizing your code into files and folders, you’ll frequently come across relative imports and adjusting sys.path.

In the next section, we’ll explore both and see how they fit into the framework for Python imports.

Parent Directory Imports

You can organize code into different folders and files to improve both readability and maintainability. However, importing modules from parent directories can be a bit tricky.

In this section, we’ll discuss two approaches to achieve this:

  1. Relative Imports

  2. Adjusting sys.path

1. Relative Imports

Relative imports allow you to import modules based on their relative position in the directory hierarchy.

You can use the dot (.) notation to refer to the current directory or double dot (..) notation to refer to the parent directory.

Suppose you have a directory structure like the following:

parent_directory/
?
??? module_a.py
?
??? sibling_directory/
    ??? module_b.py

Inside module_b.py, you can use relative imports to access module_a.py:

from .. import module_a

The double dot refers to the parent directory. It is important to note that relative imports only work if the parent directory is a package (has an init.py file).

2. Adjusting sys.path

You can also import modules from a parent directory by modifying the sys.path.

Before the import statement, you can append the parent directory path to the sys.path. First, you need to import the sys module. Then, you use the os module to get the parent directory path.

Suppose you have a directory structure like the following:

project_root/
?
??? parent_directory/
?   ??? module_a.py
?
??? current_directory/
    ??? module_b.py

In module_b.py, you can append the parent directory path to sys.path like this:

import os
import sys

parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(parent_dir)

import module_a

Now, Python will look for module_a.py in the parent directory when importing it in module_b.py.

You can use either the relative import approach or the sys.path approach to import modules from a parent directory.

How to Work With Modules and Packages

In Python, modules and packages are a way to organize and reuse code. You can use them to split up complex projects into manageable parts.

This section will discuss how to work with modules and packages in Python. We’ll also be including key concepts such as:

  1. Namespaces

  2. Variables and Definitions

  3. Import Statements

1. What Are Namespaces?

Namespaces in Python are a way to ensure that the names of variables, functions, and classes don’t conflict between different modules.

There are different levels of namespaces in Python, such as:

  • Global Namespace: Refers to the namespace of the entire module.

  • Local Namespace: Refers to the namespace within a function or class.

You can obtain a name in a particular namespace with the namespace[name] notation.

2. What Are Variables and Definitions?

In a Python script, you can define variables, functions, and classes. These definitions are stored in the namespace of the script.

By importing the script as a package, you can access and reuse its definitions in other parts of your project.

The following is an example of how to define a variable and a function in the same namespace:

# my_variable.py
my_variable = 5

def my_function(x):
    return x + my_variable

This module has a variable my_variable and a function my_function.

To run this code, you can create a new file named my_variable.py and put the code there as shown below:

Creating a new file named my_variable.py

Now, you can import this file and use it in another script as shown below:

Using the my_varaible.py module in main.py

After running the main.py file, you’ll get an output similar to the following :

Output of main.py file

3. What Are Import Statements?

You can import files, modules or packages in Python with the import statement

Some common import methods are:

  • import module_name: This method imports a module, making all its definitions accessible with the module_name.definition_name notation.

import mymodule

result = mymodule.my_function(3)
  • from module_name import some_definition: This method imports a specific definition from a module, allowing you to use it directly without the module prefix.

from mymodule import my_function

result = my_function(3)
  • from module_name import *: This method imports all definitions from a module, but it’s not recommended as it can lead to naming conflicts.

Final Thoughts

Understanding how to import from a parent directory in Python is important in maintaining an organized codebase.

This knowledge allows you to design your projects in a more modular way. It also increases the reusability of your code. By structuring your code into separate modules and packages, you can avoid repeating code and make it easier to maintain and update.

The skill to use import and from statements is most valuable when you are working on larger projects where functionalities are split across different directories.

By knowing how to correctly adjust Python’s path to import modules, you can access functionalities defined in one directory while working in another.

Remember, the key to mastering Python — or any programming language — lies in consistent practice and insatiable curiosity. So, keep exploring, keep experimenting, and keep challenging yourself.

With this quick guide, you should be well-equipped to handle any import puzzles Python throws at you. But don’t stop here. There’s a whole universe of Python techniques and tricks waiting to be discovered!

author avatar
Sam McKay, CFA
Sam is Enterprise DNA's CEO & Founder. He helps individuals and organizations develop data driven cultures and create enterprise value by delivering business intelligence training and education.

Related Posts