I have the following project and module setup:
class2.py:
from mod1.class1 import Class1
class Class2(object):
def __init__(self, c1: Class1):
self.c1 = c1
class2.py:
from mod2.class2 import Class2
class Class1(object):
def __init__(self):
self.c2 = Class2(self)
main.py:
from mod2.class2 import Class2
c2 = Class2()
The idea is that when a parent class initializing a child class, it introduces itself to the child class. This way the child class can call parent class methods.
This pattern works fine in strongly typed languages like C#.
When I run main.py
, I get the following error:
Traceback (most recent call last):
File "C:\Projects.Personal\exp02\main.py", line 2, in <module>
from mod2.class2 import Class2
File "C:\Projects.Personal\exp02\mod2\class2.py", line 2, in <module>
from mod1.class1 import Class1
File "C:\Projects.Personal\exp02\mod1\class1.py", line 1, in <module>
from mod2.class2 import Class2
ImportError: cannot import name 'Class2' from partially initialized module 'mod2.class2' (most likely due to a circular import) (C:\Projects.Personal\exp02\mod2\class2.py)
Process finished with exit code 1
I just need to let Class2 know about the type of Class1.
Why am I getting such error?
What is the proper pattern to do this in Python?
Update #1
I understand that this is a circular import as it is specifically stated in the error message.
The idea explained in this article (https://stackabuse.com/python-circular-imports/) is not applicable here. Here I have Classes not module functions. I just need to annotate a variable. My code sample is very much simplified. The actual classes code is large. I don't want to combine them in one file.
IMO, This is a valid pattern and I can do it in Java or C#.
How can I implement the idea in Python?
CodePudding user response:
Use the TYPE_CHECKING
flag from typing
and make the class a string.
At runtime TYPE_CHECKING
is False so the import will not execute, but a type checker should find this acceptable.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from mod1.class1 import Class1
class Class2(object):
def __init__(self, c1: "Class1"):
self.c1 = c1
CodePudding user response:
You have a circular import. Your Class1 and Class2 files are attempting to import each other- i'd suggest using one file that imports both classes.