0
class FakeBase(object):
    def __init__(self, *args):
        pass

class Parent(FakeBase):
    def __init__(self, x=1, *args):
        super().__init__(x, *args)
        self.var1 = x

class Parent2(FakeBase):
    def __init__(self, x=3, y=4, *args):
        super().__init__(x, y, *args)
        self.var2 = x
        self.var3 = y

class Child(Parent, Parent2):
    def __init__(self, z, *args):
        super().__init__(*args)
        self.var4 = z

childObject = Child("var4", "var3", "var1", "var2")
print(childObject.var1)
print(childObject.var2)
print(childObject.var3)
print(childObject.var4)

The result is:

var3
var3
var1
var4

I just started dealing with Python multiple inheritance.

Here, I am only able to call the super().__init__(x) with one parameter. And it will only call the parent's __init__(). I want to initial var2 and var3 also. How to do that?

Getting hits from your answers, I tried to modified my code.

But, still not getting the way to initial all four parameters. And none of your answers did neither.

Thanks and still waiting for the answer.

user1947415
  • 933
  • 4
  • 14
  • 31
  • 2
    Make everything handle `*args` and `**kwargs` or have the same signature. Also, why is everything a class attribute? – jonrsharpe Jun 15 '14 at 21:34
  • possible duplicate of [Python's Multiple Inheritance: Picking which super() to call](http://stackoverflow.com/questions/14206015/pythons-multiple-inheritance-picking-which-super-to-call) – Ruben Bermudez Jun 15 '14 at 21:52
  • @jonrsharpe, yes that is not my intent. fixed. – user1947415 Jun 16 '14 at 13:06

2 Answers2

0

Here's a solution building on @jonrsharpe's suggestion. Method uses *args signature for generic variables, which are passed to parent(s). The specific variable z is captured separately and used by the class.

source

class parent(object):
    var1=1
    def __init__(self,x=1):
        self.var1=x

class parent2(object):
    var2=11
    var3=12
    def __init__(self,x=3,y=4):
        self.var2=x
        self.var3=y

    def parprint(self):
        print(self.var2)
        print(self.var3)

class child(parent, parent2):
    var4=5
    def __init__(self, z, *args):
        super(child,self).__init__(*args)
        self.var4 = z

childobject = child(9,"var3")
print(childobject.var1)
print(childobject.var2)
print(childobject.var3)
print(childobject.var4)
childobject.parprint()

output

var3
11
12
9
11
12
johntellsall
  • 14,394
  • 4
  • 46
  • 40
0

What's happening is the following:

  1. Child grabs "var4" to its argument z and passes on the args list ["var3", "var1", "var2"] to Parent.
  2. Parent grabs "var3" to its argument x and passes on the x and args list ["var1", "var2"] to Parent2 (so it both grabs and passes the same value "var3").
  3. Parent2 grabs "var3" and "var1" and passes the args list ["var2"] to the FakeBase.

You can use *args if you know the Method Resolution Order (MRO), but the MRO may change if you create new subclasses or superclasses, making your code very unstable. The better way is to use keyword arguments **kwargs instead. Each class grabs the variable it needs and passes along the rest.

class FakeBase(object):
    def __init__(self, **kwargs):
        pass


class Parent(FakeBase):
    def __init__(self, var1=1, **kwargs): # Takes var1 out from **kwargs.
        super().__init__(**kwargs)  # Passing on the rest {}.
        self.var1 = var1


class Parent2(FakeBase):
    def __init__(self, var2=3, var3=4, **kwargs): # Takes var2 and var3 out from **kwargs.
        super().__init__(**kwargs)  # Passing on the rest {var1: "var1"}.
        self.var2 = var2
        self.var3 = var3


class Child(Parent, Parent2):
    def __init__(self, var4, **kwargs):  # Takes var4 out from **kwargs.
        super().__init__(**kwargs)  # Passing on the rest {var1: "var1", var2: "var2", var3: "var3"}.
        self.var4 = var4

By writing it this way the MRO doesn't matter and he order of the arguments when initializing Child doesn't matter either:

childObject = Child(var1="var1", var2="var2", var3="var3", var4="var4")
print(childObject.var1, childObject.var2, childObject.var3, childObject.var4)
# OUTPUT: var1 var2 var3 var4

childObject = Child(var4="var4", var1="var1", var3="var3", var2="var2")
print(childObject.var1, childObject.var2, childObject.var3, childObject.var4)
# OUTPUT: var1 var2 var3 var4
Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50