3

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__(...)
Sal
  • 1,653
  • 6
  • 23
  • 36
  • 'In order to avoid circular imports when I import classA I added the classB import to the end of classA.py' This is actually a circular import... you should not import classB at all in classA.py, since A is the parent it doesn't need to have ClassB imported... – alec_djinn Feb 03 '16 at 14:33
  • 1
    But `classA` has a method that returns an instance of `classB` so I need to import it, right? – Sal Feb 03 '16 at 14:34
  • Then to import first A and then B is the best way if you want to keep them in separate files. – alec_djinn Feb 03 '16 at 14:39
  • That's what I'm asking, is this the only and/or best way to do this? It works but I thought it might not be necessary. – Sal Feb 03 '16 at 14:44

2 Answers2

3

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?.

Community
  • 1
  • 1
Borys Serebrov
  • 15,636
  • 2
  • 38
  • 54
  • 3
    I guess I should have pointed out that the above issue is a result of splitting up a huge module into separate files. – Sal Feb 04 '16 at 00:13
  • @Sal I understand that you have some reasons to split these classes into the separate files, but as you can see in this case it leads to the problem which is more serious than the large file. This is my personal opinion, but I would keep them in the same module or refactor the code to remove this circular dependency. – Borys Serebrov Feb 04 '16 at 00:22
  • I appreciate the comments. Do you really think this is a 'serious' problem? I only posted the question because I thought typing out the extra import line every time was annoying. – Sal Feb 04 '16 at 01:43
  • 1
    @Sal this is annoying only until you remember about this problem, few months later you'll be puzzled by unexpected error trying to remember what should be done it order to fix it. It will be even worth if some other developer will stuck into it. Check also [this](http://stackoverflow.com/questions/10113383/handle-circular-dependencies-in-python-modules) and [this](http://stackoverflow.com/questions/1356304/are-circular-class-dependencies-bad-from-a-coding-style-point-of-view). – Borys Serebrov Feb 04 '16 at 08:42
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

Gerzson
  • 97
  • 1
  • 2