mtber75
mtber75

Reputation: 978

How would a parent class call its own method within itself in Python

I am trying to create the concrete class Val15 class with the Mixins, MyCollection, Val5, Val10. Val15 is trying to inherit values from MyCollection. When Val15 is instantiated, I am trying to call both Val10's and Val5's value and add them to Val15, values.

However, it turns out that Val15 will inherit only Val10's value and all the classes will call Val10's value. How exactly can you overturn this problem?

class MyCollection(object):
    def __init__(self):
        super().__init__()
        self.values = []


class MyMessage(object):
    def __init__(self):
        super().__init__()

    def message(self):
        print('Hello World')


class Val10(object):
    def __init__(self):
        super().__init__()
        print('Call 10')
        self.values.append(self.value())

    def value(self):
        print('Value 10')
        return 10


class Val5(object):
    def __init__(self):
        super().__init__()
        print('Call 5')
        self.values.append(self.value())

    def value(self):
        print('Value 5')
        return 5


class Val15(Val10, Val5, MyMessage, MyCollection):
    def __init__(self):
        super().__init__()

    def my_sum(self):
        return sum(self.values)


val15 = Val15()
val15.my_sum()
val15.message()

# Result:
# Call 5
# Value 10
# Call 10
# Value 10
# Hello World

Upvotes: 0

Views: 86

Answers (1)

zvone
zvone

Reputation: 19362

This is the interesting part:

class Val10(object):
    def value(self):
        return 10

class Val5(object):
    def value(self):
        return 5

To get the sum of parents' values, you have to call each of them:

class Val15(Val10, Val5):
    def value(self):
        return Val10.value(self) + Val5.value(self)

Alternative solution

Another approach is to define that value always returns the sum of all inherited values, whatever they may be, without knowing which parent classes' value to call:

class Val10:
    def value(self):
        previous = getattr(super(), 'value', lambda: 0)()
        return previous + 10

class Val5:
    def value(self):
        previous = getattr(super(), 'value', lambda: 0)()
        return previous + 5

class Val15(Val10, Val5):
    def value(self):
        return getattr(super(), 'value', lambda: 0)()

Val15().value()  # 15

This solution does not make any assumptions about the way inheritance is going to be configured.

Remarks:

  • The answer assumes that this is Python 3, because of the super() syntax
  • getattr(super(), 'value', lambda: 0) returns the bound value method of the parent class, if such exists, or defaults to a function which returns 0.

Upvotes: 1

Related Questions