I am sure there must be a duplicate of my question, but have not found it. I am a novice trying to finally learn OOP. In the following code I have three levels of classes - the sub-class seems to be inheriting attributes from the base class, but not from its immediate parent:
class Option(object):
def __init__(self, *args, **kwargs):
self.strike_type = kwargs.get('strike_type')
self.multiplier = kwargs.get('mutiplier', 100)
self.exp_months = kwargs.get('exp_months', 1)
self.strike_steps = kwargs.get('strike_steps', 1)
class Put(Option):
def __init__(self, *args, **kwargs):
super(Option, self).__init__(*args, **kwargs)
self.option_type = 'put'
class ShortPut(Put):
def __init__(self, *args, **kwargs):
super(Put, self).__init__(*args, **kwargs)
self.ratio = kwargs.pop('ratio', 1)
self.qty_mult = -1
shortput = ShortPut(strike_type=-1, exp_months=6, strike_steps=2, ratio=2)
shortput.ratio #class ShortPut
2
shortput.exp_months #class Option
6
shortput.option_type #class Put
AttributeError: 'ShortPut' object has no attribute 'option_type'
dir(shortput) #dunder entries removed
['exp_months',
'multiplier',
'qty_mult',
'ratio',
'strike_steps',
'strike_type']
So the attribute works fine if I cut and paste it into either Option or ShortPut. I have also tried change the order in the init modules, but it doesn't seem to make a difference if the call to super is made before or after the other attributes. The arguments are flowing through from ShortPut to Put to Option, but it doesn't seem to like the attribute in the middle class.
followup - I can't call the put class directly:
put = Put(strike_type=-1, exp_months=6, strike_steps=2, ratio=2)
TypeError: object.__init__() takes no parameters
Any insights into what is going on would be greatly appreciated.
1 Answer 1
When you use super, the first argument should be the class from which you are making the call, not its superclass. So in Put you should use super(Put, self) and in ShortPut you should use super(ShortPut, self).
2 Comments
super is exactly this: you don't have to hard-code the superclass, thus making easier using multiple-inheritance code where the mro may not be obvious.