Introduction
The import error might occur in numerous cases and scenarios. Some classic examples of import error have been explained in the following tutorials:
- [Fixed] ImportError: No module named requests
- How to Fix โImportError: No module named pandasโ [Mac/Linux/Windows/PyCharm]
In this article, you will learn about another import error that commonly occurs while you are dealing with packages and dependencies in Python.
A Quick Recap to Import Statement and ImportError
In Python, the import
statement serves two main purposes:
- It is used to search for the module specified by its name, then load and initialize it if the module is required.
- It additionally defines a name in the local namespace within the scope of the import statement. This local name would then be able to be used to reference the accessed module throughout the whole code.
If an import
statement experiences difficulty in successfully importing a module, it raises an ImportError
.
Commonly, such an issue occurs because of a faulty installation or an invalid path, which will usually raise a ModuleNotFoundError
in Python 3.6 and newer versions.
Problem Formulation
Let’s try understand the problem a bit better before we go into the solution!
In Python "ImportError: cannot import name"
error generally occurs when the imported class is not accessible, or the imported class is in a circular dependency.
The following are the major reasons for the occurrence of "ImportError: cannot import name":
- The imported class is in a circular dependency.
- The imported class is not available or has not been created.
- The imported class has been misspelled.
- The imported class from a specific module is misplaced.
- The imported class is not present in the Python library. This generally happens while importing external libraries.
Example: Consider you have two modules: x.py
and y.py
, as shown below.
These files represent how the ImportError
occurs when there is a circular dependency between them, leading to a dead loop situation.
Let’s have a look at the contents of the first module:
x.py
from x import x_1 def y_1(): print('y1') x_1() def y_2(): print('y2') if __name__ == '__main__': y_1()
Let’s have a look at the contents of the second module:
y.py
from y import y_2 def x_1(): print('x1') y_2()
Can you find the circular dependency?
Output:
ImportError: cannot import name 'x_1' from partially initialized module 'x' (most likely due to a circular import)
The error occurred because both the Python files, i.e., x
and y
, attempted to load each other simultaneously.
The y
module tried to load the x
module while the x
module attempted to load the y
module.
This created a circular load dependence leading to an error in the heap memory. To eliminate the ImportError
, you have to get rid of the circular dependency.
Solution 1: Simply Use Import [Avoid from X import Y]
Simply put, the problem is occurring because we are trying to access the contents of one module from another simultaneously before the contents of the module are ready/initialized.
This happens particularly because you are using: from x import x_1
and from y import y_2
.
Python can detect circular dependencies and prevent dead loops.
Essentially what happens is that an empty placeholder is created for the module (i.e., it does not contain any content).
After the modules that are circularly dependent are compiled, Python automatically updates the imported module.
However, for Python to resolve the problem of circular dependency, you must use import x
only instead of importing a particular content of the module with the help of the from
statement.
As you are no longer trying to load the individual contents of the module at the top level, Python gets ample time to compile the module, thereby handling the circular dependency by itself.
Let’s have a look at the following code to understand how this works:
x.py
import x def y_1(): print('y1') x.x_1() def y_2(): print('y2') if __name__ == '__main__': y_1()
And on to the second module!
y.py
import y def x_1(): print('x1') y.y_2()
Now, does it work or does Python raise a circular dependency error?
Output:
y1 x1 y2
Yes, it works!
Solution 2: Re-Order Position Of Import Statement
In the above example, you can avoid the circular dependency by reformating the sequence of import
statements.
Thus, instead of importing the y
module at the beginning within the x
module, you can import it later, as shown in the following snippet:
x.py
def x_1(): print('x1') y_2() from y import y_2
Output:
y1 x1 y2
Conclusion
To sum things up, you can solve the “ImportError: Cannot import name X
” Error by resolving the circular dependencies.
You can do that either by eliminating the usage of from x import y
form of importing contents from a module and simply using the import
statement to import the entire module.
Another workaround to this error is to change the position of the import statements accordingly within your code.
I hope this tutorial answered your queries. Please stay tuned and subscribe for more solutions and interesting discussions in the future. Happy coding!
Programmer Humor
โ Question: How did the programmer die in the shower? โ ๏ธ
โ Answer: They read the shampoo bottle instructions:
Lather. Rinse. Repeat.
Recommended Course:
- Do you want to master the most popular Python IDE fast?
- This course will take you from beginner to expert in PyCharm in ~90 minutes.
- For any software developer, it is crucial to master the IDE well, to write, test and debug high-quality code with little effort.