Open In App

Python Circular Imports

Last Updated : 15 May, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

The Circular Imports in Python programming occur when two or more modules mutually depend on each at the same time forming a loop between them. These modules' dependency on each other often results in the program getting stuck and generating circular import errors.

What does the Python Circular Error Mean?

Sometimes there may occur a situation when, let us say a person, A needs a person B to do some work. But simultaneously person B needs person A to do some work. This causes both A and B to depend on each other. A similar situation occurs in programming while importing modules and is known as Circular imports. In this article, we will learn more about circular imports and what problems they may cause.

Analyze Circular Imports in Python

Let us see a simple example to know how this error occurs.

Example: Here we will create two modules, 'mod1' and 'mod2' that contains a function 'display1' and 'display2', respectively to print some data. We will import 'mod1' into 'mod2' and vice-versa so that they depend on each other simultaneously and use their functions accordingly.

mod1.py

Python
# import module2
import mod2

def display1():
    print("I am display1 from module 1")

# using mod2's function display2    
mod2.display2()

mod2.py

Python
# importing module 1
import mod1

def display2():
    print("I am display2 of module 2")
    
# calling mod1's function display1
mod1.display1()

Output:


python-circular-imports-error
Python Circular Import


Fix Python Circular Import Error

Now that we are familiar with how the circular import occurs in Python, we will see how we can avoid and fix this issue.

  • Import modules when needed
  • Use Python importlib library
  • Create a Module for shared code

Import the Module when needed

One simple way to fix circular imports is to import a module when it is needed. We usually import a module at the beginning of the code, but this time to avoid circular import issue, we import the module inside a function where it is required to do the job.

Example: Unlike previous example, this time we will import the module just before we require its function in another module.

mod1.py

Python
def display1():
    print("I am display1 from module 1")

# import module when needed
import mod2
mod2.display2()

mod2.py

Python
def display2():
    print("I am display2 of module 2")

# import module when needed
import mod1
mod1.display1()

Output:

When mod1.py is executed

I am display2 of module 2
I am display1 from module 1
I am display2 of module 2

Use Python importlib module

Python's importlib module is used to dynamically import modules during runtime in the program. Here to avoid circular imports we have used importlib module's import_module() function.

Example: In this example, instead of simple python module import statement we are importing modules using the import_module() function and providing the module to be imported as the parameter.

mod1.py

Python
# import importlib module
import importlib

def display1():
    print("I am display1 from module 1")

# import mod2 using importlib.import_module()
module = importlib.import_module("mod2")
module.display2()

mod2.py

Python
# import importlib module
import importlib

def display2():
    print("I am display2 of module 2")

# import mod1 using importlib.import_module()
module = importlib.import_module("mod1")
module.display1()

Output:

I am display2 of module 2
I am display1 from module 1
I am display2 of module 2

Create a Module for shared code

Another way to avoid circular imports is by creating a new module. This module will contain all the content that is shared among different modules which was the main reason for dependency. Now the modules can easily refer to this new module without causing circular import issue.

Example: In this example we will create an extra module 'common.py' that will contain the shared functionalities of the previous two modules.

common.py

Python
def display3():
    print("I am display 3 from common.py")

mod1.py

Python
# import common module
import common

def display1():
    print("I am display1 from module 1")    
    common.display3()

display1()

mod2.py

Python
# import common module
import common

def display2():
    print("I am display2 from module 2")
    common.display3()

display2()

Output:

On executing the mod1.py, we will get the following output.

I am display1 from module 1
I am display 3 from common.py

Next Article
Article Tags :
Practice Tags :

Similar Reads