kobs20
kobs20

Reputation: 125

Why is super().__init__(*args,**kwargs) being used when class doesn't specify a superclass?

I understand why super() is used when a class is a subclass of a superclass, but what is the superclass of a class that doesn't specify the superclass in the subclass parameters? Here's my code:

import random


class Sneaky:
    sneaky = True

    def __init__(self, sneaky=True, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.sneaky = sneaky

    def hide(self, light_level):
        return self.sneaky and light_level < 10


class Agile:
    agile = True

    def __init__(self, agile=True, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.agile = agile

    def evade(self):
        return self.agile and random.randint(0, 1)

Upvotes: 10

Views: 7017

Answers (1)

unutbu
unutbu

Reputation: 880547

Suppose Sneaky is used as part of a multiple inheritance class structure such as:

class Sneaky:
    sneaky = True

    def __init__(self, sneaky=True, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.sneaky = sneaky

    def hide(self, light_level):
        return self.sneaky and light_level < 10

class Person:
    def __init__(self, human=True, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.human = human

class Thief(Sneaky, Person): 
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)


t = Thief()
print(t.human)
# True

Since

In [62]: Thief.mro()
Out[62]: [__main__.Thief, __main__.Sneaky, __main__.Person, object]
  • Thief.__init__'s super().__init__(*args, **kwargs) calls Sneaky.__init__.
  • Sneaky.__init__'s super().__init__(*args, **kwargs) calls Person.__init__.

If the super().__init__ call were removed from Sneaky.__init__, then t.human would raise

AttributeError: 'Thief' object has no attribute 'human'

because Person.__init__ would not get called.

Upvotes: 18

Related Questions