2013-08-29 4 views
1

Я уверен, что должен быть дубликат моего вопроса, но не нашел его. Я новичок, пытающийся наконец узнать ООП. В следующем коде у меня есть три уровня классов - суб-класс, кажется, унаследовав атрибуты из базового класса, но не от его непосредственного родителя:Атрибуты класса Python, не наследующие

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'] 

Так атрибут работает отлично, если я вырезать и вставить его в любой вариант или ShortPut. Я также попытался изменить порядок в модулях init, но, похоже, не имеет никакого значения, если вызов super выполняется до или после других атрибутов. Аргументы идут от ShortPut до Put to Option, но это не похоже на атрибут в среднем классе.

Followup - Я не могу назвать класс положить непосредственно:

put = Put(strike_type=-1, exp_months=6, strike_steps=2, ratio=2) 
TypeError: object.__init__() takes no parameters 

Любые идеи в том, что происходит было бы весьма признателен.

ответ

2

Когда вы используете super, первым аргументом должен быть класс, из которого вы делаете вызов, а не его суперкласс. Поэтому в Put вы должны использовать super(Put, self), а в ShortPut вы должны использовать super(ShortPut, self).

+0

+1 - Один из пунктов использования 'super' - это именно то, что вам не нужно жестко закодировать суперкласс, тем самым упрощая использование кода с множественным наследованием, где' mro' может быть не очевидным. – Bakuriu

+0

Я получаю это сейчас, спасибо. Что меня смутило, так это то, что я думал, что аргумент self относится к классу, но теперь я вижу, что он привязан к данному экземпляру класса (например, я сказал, что все еще изучаю ООП). –

Смежные вопросы