-1

I have main.py, parentClass, class_A and class_B in 4 different files.

from main.py I call class_A (subclass of parentClass) and from class_A I need to call class_B, in which I want all the methods of class_A and parentClass. How can I do it?

class parentClass(object):
    def __init__(self):
       ......

class class_A(parentClass):
   def __init__(self):
       super().__init__()

   def method1(self):
       ....

   def method2(self):
       ....

   def call_class_B(self)
       x = class_B()


class class_B(?):
   def __init__(self):
       ...
   here I need to call the method of the other classes

basically class_B is a subclass of class_A but it is called from class_A

disable0
  • 61
  • 1
  • 6
  • In your scenario, you can safely inherit from `class_A` in your `class_B` (i.e. `class class_B(class_A): ...`) and it will get all the methods from both `class_A` and `parentClass`. – zwer Jun 11 '17 at 12:46
  • With your description you need to do what zwer says. your line where you reference class_B() as writen will make a NEW class_b which in your code snippit will run the __init__ method. – LhasaDad Jun 11 '17 at 13:17
  • that is what I tried, and the output is "ImportError: attempted relative import with no known parent package – disable0 Jun 11 '17 at 13:35

1 Answers1

0

The Problem

I believe, based on the first line of your question, that the primary issue here is avoiding a circular import. If each of these classes is in a separate file, it will be difficult to make sure that the right parent class is defined when and how you need it.

The Solution

One solution to this is to set the whole thing up as a module (in a directory called my_module) containing the following files:

__init__.py:

from .parent import Parent

class ClassB(object):
    pass

from .a import ClassA
from .b import ClassB

parent.py

class Parent(object):
    def meth(self):
        print("From Parent")

a.py

import my_module

class ClassA(my_module.Parent):
    def get_a_B(self):
        return my_module.ClassB()

    def meth(self):
        super().meth()
        print("From ClassA")

b.py

import my_module

class ClassB(my_module.ClassA):

    def meth(self):
        super().meth()
        print("From ClassB")

Then, outside of my_module, you could have the following main.py:

from my_module.b import ClassB

if __name__ == "__main__":
    myB = ClassB()
    my_other_B = myB.get_a_B()
    my_other_B.meth()

which will, when run (Python 3.5) print the following output:

From Parent
From ClassA
From ClassB

What's Going On?

Inside the __init__ file for the module, we declare a "dummy" version of ClassB. We use this to define ClassA in a.py but before we actually use ClassA, it has been replaced by the real ClassB defined in b.py, thereby giving us the desired behavior.

The Better Solution

All of this does have a bit of a code smell, though. If ClassA and ClassB are really so tightly bound up in one another, it's possible they should be a single class. At the very least, they should probably be defined in the same file, which will, as zwer pointed out, work just fine.

Alternatively, you might look at wrapping some of the functionality of the Parent class and ClassA rather than inheriting, but we'd probably need more information about exactly what you're doing to say what the best solution is.

wphicks
  • 355
  • 2
  • 9
  • exactly... it is a circular import. at the beginning it was only one single class, than I tried to split in to different file just to avoid thousand of lines. It seems the best solution is keeping everything in the same class&file – disable0 Jun 11 '17 at 13:55