Fabian Zamora
Fabian Zamora

Reputation: 31

Problem with Multiple inheritance with super() in Python. How does Python's super() work with?

I am practicing multiple inheritances in Python. Without the super()., everything goes well using Wizard.init(self, name, power) and Archer.init(self, name, arrows), but I replaced by super() it shows the following error.

" super().init(name, power, arrows)

TypeError: init() takes 3 positional arguments but 4 were given "

Any help is highly appreciated.

class User():

    def sign_in(self):
        print("logged in")



class Wizard(User):
    def __init__(self, name, power):
        self.name1 = name
        self.power = power

    def attack(self):

        print(f"attacking with power of {self.power}")

class Archer(User):

    def __init__(self, name, arrows):
        self.name = name
        self.arrows = arrows

    def check_arrows(self):
        print(f"{self.arrows} remaining")

    def run(self):
        print ("ran really fast")


class HybridBorg(Wizard, Archer):
    def __init__(self, name, power, arrows):
        super().__init__(name, power, arrows)
        # Archer.__init__(self, name, arrows)
        # Wizard.__init__(self, name, power)

hb1 = HybridBorg("Andres", 34, 50)
print(hb1.check_arrows())

Upvotes: 1

Views: 144

Answers (1)

jsbueno
jsbueno

Reputation: 110271

Two things: 1) you have to call super on all your cooperative classes, up to your base class (or up to "object", when you do not have one) 2) in each class, accept any number of keyword parameters and "consume" those of interest - avoiding breaks when an unknown parameter is seen.

Your code could be like this:

class User():
class User:
    def sign_in(self, name):  # <- no extra kwargs: any remainign keywoed argument will break!
        self.name = name
        print("logged in")


class Wizard(User):
    def __init__(self, power, **kwargs):
        self.power = power
        super.__init__(**kwargs)

    def attack(self):
        print(f"attacking with power of {self.power}")



class Archer(User):

    def __init__(self, arrows, **kwargs):
        self.arrows = arrows
        super().__init__(**kwargs)

    def check_arrows(self):
        print(f"{self.arrows} remaining")

    def run(self):
        print ("ran really fast")


class HybridBorg(Wizard, Archer):
    def __init__(self, name, power, arrows): # Or you could accept and forward "**kwargs",
                                             # buty then, tools like linters and IDEs would 
                                             # not be able to show the expected parameters.
        super().__init__(name=name, power=power, arrows=arrows)

        # if there is no specific code here, actually, this __init__ could be simply ommited

hb1 = HybridBorg("Andres", 34, 50)
print(hb1.check_arrows())

Upvotes: 1

Related Questions