Foucault
Foucault

Reputation: 39

How to do partial inheritance in Python?

I have a class, Bond, which has as instances a term that we’ll invest in them, a certain amount that will be invested, a minimum price, a minimum term and yearly interest rate. The subclass LongTerm has minimum term of 2 years, a minimum amount of $250 and a yearly interest of 2.5%.

The following code works correctly:

class Bond(object):
    def __init__(self,minTerm, term,amount,minPrice,yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate

class LongTerm(Bond):
    def __init__(self, term,amount,minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minAmount = minAmount
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate

But when I use the partial inheritance function

super().__init__(term,amount,minPrice)

it shows an error:

TypeError: __init__() missing 2 required positional arguments: 'minPrice' and 'yrlyRate'

Code using super():

class Bond(object):
    def __init__(self,minTerm, term,amount,minPrice,yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate

class LongTerm(Bond):
    def __init__(self, term,amount,minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        super().__init__(term,amount,minPrice)
        self.term = term
        self.amount = amount
        self.minPrice = minPrice

Why should not I be able to partially inherit only some instances of the superclass?

Upvotes: 0

Views: 415

Answers (2)

TheLazyScripter
TheLazyScripter

Reputation: 2665

If your subclass requires less information than your superclass, then perhaps you don't need to use inheritance. In the event that it's not possible to modify the original class then perhaps composition would be more helpful.

Method 1. With general class inheritance

class Bond:
    def __init__(self, minTerm, term, amount, minPrice, yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate


class LongTerm(Bond):
    def __init__(self, term, amount, minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        super().__init__(minTerm, term, amount, minPrice, yrlyRate)
        self.minAmount = minAmount

Method 2. With overriding example and defaulting arguments

class Bond:
    def __init__(self, minTerm, term, amount, minPrice, yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate
    
    def short_term_only(self):
        #do some stuff

        
class LongTerm(Bond):
    def __init__(self, term, amount, minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        # In the event that maybe we don't care about some of the information or methods
        # in the parent we can set them to none or even over-ride the methods
        super().__init__(minTerm, None, None, minPrice, yrlyRate)
        self.minAmount = minAmount
        
    def short_term_only(self):
        raise NotImplementedError

Method 3. With class composition

The concern with this method is that methods available to class Bond won't be inherently available to class LongTerm:

class LongTerm:
    def __init__(self, term, amount, minPrice, minAmount = 1000, minTerm = 5, yrlyRate = 0.05):
        self.bond = Bond(minTerm, term, amount, minPrice, yrlyRate)
        self.minAmount = minAmount

Upvotes: 2

Vivek
Vivek

Reputation: 344

I think what you need is something like this...

class Bond:
    def __init__(self, term, amount, minPrice, minTerm, yrlyRate):
        self.term = term
        self.amount = amount
        self.minPrice = minPrice
        self.minTerm = minTerm
        self.yrlyRate = yrlyRate

    def __repr__(self):
        return f"Term: {self.term}, Amount: {self.amount}, MinPrice: {self.minPrice}, MinTerm: {self.minTerm}, YearlyRate: {self.yrlyRate}"

class LongTerm(Bond):
    def __init__(self, term, amount, minPrice, minTerm=5, yrlyRate=0.05, minAmount=1000):
        super().__init__(term=term, amount=amount, minPrice=minPrice, minTerm=minTerm, yrlyRate=yrlyRate)
        self.minAmount = minAmount

print(LongTerm(term=1, amount=23, minPrice=45.2))

Upvotes: 1

Related Questions