'Python circular imports with inheritance

I have a parent and child class, where a parent's method returns an instance of the child. Both classes are in separate files classA.py and classB.py. In order to avoid circular imports when I import classA I added the classB import to the end of classA.py (as shown below). Everything worked well and I was able to properly use classA in my code.

Now I'm having issues if I want to use ONLY classB. For example, if I run

from classB import ClassB

I get the following error:

File "classA.py", line 269, in <module>
    from classB import ClassB
ImportError: cannot import name ClassB

If I run:

from classA import ClassA
from classB import ClassB

then everything works perfectly and I can use both classes. Is there a way to only import classB or must I ALWAYS first import classA and then classB?

classA.py

class ClassA():
    def __init__(self, ...):
        ....

    def someMethod(self, ...):
        ...
        return ClassB(...)

from classB import ClassB

classB.py

from classA import ClassA

class ClassB(ClassA):
    def __init__(self, ...):
    super(ClassB, self).__init__(...)


Solution 1:[1]

The obvious solution is to put both classes into the same file (same module). They are tightly related, so it makes perfect sense and no "hacks" (placing the import at the end of file) and workarounds (special order of imports) will be needed.

Check also these sources: How many Python classes should I put in one file?, Is it considered Pythonic to have multiple classes defined in the same file?.

Solution 2:[2]

You can import ClassB in ClassA locally where you use it (in someMethod)

class ClassA():
    def __init__(self, ...):
        ....

    def someMethod(self, ...):
        from classB import ClassB
        ...
        return ClassB(...)

This way I could avoid circular import error

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Gerzson