In python, a module can be made by importing other modules. In some cases, a Circular dependency is created. Circular dependency is the case when some modules depend on each other. It can create problems in the script such as tight coupling, and potential failure.
To run the script without any error the Circular dependency has to be removed. Circular dependency can be created in many ways. With a well-designed program, these cases can be avoided.
Python Circular Imports:
Circular importing is a conceptual error that is formed due to circular dependency created with the import statement in our Python program.
- Python Circular Imports is a type of Circular dependency. It occurs in python when two or more models import each other and it repeats the importing connection into an infinite circular call.
- With Circular Imports, the python script gives an error. To run the python script it has to be removed and it is very difficult to find and remove the script manually.
- Circular imports are created because of the bad coding design and implementation-related logical anomalies.
Here is a situation shown using three separate programs:
# module1 created import module2 def function1(): module2.function2() def function3(): print('Hasta la vista, Gaurav!') # module 2 import module1 def function2(): print('Hey, Gaurav') module1.function3() # __init.py import module1 module1.function1()
Here, we have defined three programs. 2 of them are treated as modules. In the first code function1() has been called that has a module2.function2() within itself as the calling function. The function2() of module 2 again has a print() and function3 and the body of function3() has some print().
Finally, the __init__.py is calling module1.function1(). This circular calls of importing statements and their associated function will create an error.
When Python performs the importing of a module, it verifies and goes through the module registry to identify if the module was already imported. In case the module has already been there registered, Python uses its existing object from cache.
The module registry is nothing but a data structure or tabular structure containing information about multiple imports (predefined and user defined) of modules that were initialized and indexed with module name(s). Developers can access this table using sys.modules.
Fixing Circular Imports in python
There are many ways by which Circular imports can be avoided. Some of them are:
- Change Name of Working python script
- Import the module
- Avoid Circular Import
- Merge modules
- Import when need
Change Name of working python script:
Changing the name of the Working file different from the module which is imported in the script can avoid the Circular Imports problem.
Import the module:
Avoid importing objects or functions from a module that can cause Circular Imports. It is good to import the whole module to avoid the Circular Import.
Avoid Circular Import:
There are many cases where one module function depends on another model which in turn depends on it. This case mostly creates Circular Imports.
When one module depends on another model and that module depends on first then it is good practice to Merge both the modules to avoid Circular Imports.
# one module def fun1(): print('In function 1') fun2() def fun2(): print('In function2') function3() def function3(): print('In function 3') fun1()
Here, merge both module1 and module2, so that the user-defined functions within them come under one module.
Import when need:
The python module can be imported anywhere in the program. It is not necessary for python to first import the module and start working over it. Importing the module before one line where it is needed to avoid Circular Import.
def fun1(): print('In function 1') import newmodule newmodule.fun3() def fun2(): print('In function 2')
Here, In function one imports the newmodule before calling the fun3.
We hope this article has given a crisp idea on how to stay ahead of circular import issue. We learn about Circular dependency, Circular Imports, and various ways to solve the problem of Circular imports. Circular Imports reduce code reusability and create infinite recursions leading to inefficient programming and memory leaks, and can even lead to cascade effects. It is good programming practice to avoid Circular Imports.