2012-06-24 2 views
24

подклассов питона dict работает, как ожидалось:Как подкласс OrderedDict?

>>> class DictSub(dict): 
...  def __init__(self): 
...   self[1] = 10 
...   
>>> DictSub() 
{1: 10} 

Однако, делать то же самое с collections.OrderedDict не работает:

>>> import collections 
>>> class OrdDictSub(collections.OrderedDict): 
...  def __init__(self): 
...   self[1] = 10 
...   
>>> OrdDictSub() 
(…) 
AttributeError: 'OrdDictSub' object has no attribute '_OrderedDict__root' 

Таким образом, реализация OrderedDict использует личный __root atribute, что предотвращает подкласс OrdDictSub от поведения, как подкласс DictSub. Зачем? Как можно наследовать от OrderedDict?

+2

Почему downvote? – EOL

ответ

33

Вам нужно вызвать OrderedDict.__init__ из ваших __init__:

class OrdDictSub(collections.OrderedDict): 
    def __init__(self): 
     super(OrdDictSub, self).__init__() 

Вы не дали OrderedDict возможность инициализировать себя. Технически вы хотите сделать это для своего подкласса dict, так как вы хотите полностью инициализировать dict. Тот факт, что dict работает без этого, - это просто удача.

+0

Спасибо. На самом деле, я плохой. Верно, что на меня повлиял дикт. Я даже задал вопрос о дикторе некоторое время назад (http://stackoverflow.com/questions/2033150/subclassing-dict-should-dict-init-be-called)! – EOL

+6

Вам не нужны аргументы и кварты в init? 'def __init __ (self, * args, ** kwargs): super (OrdDictSub, self) .__ init __ (* args, ** kwargs)' – hobs

2

Try инициализации суперкласса в методе __init__:

def __init__(self): 
    collections.OrderedDict.__init__(self) 
    self[1] = 10 

Это нормальный способ инициализации подкласс. У вас не есть, чтобы вызвать метод superclass __init__ в целом, но если вы не знаете о реализации суперкласса, вам действительно нужно позвонить __init__.

+1

Используйте 'super()' для вызова методов суперкласса – astynax

+1

@astynax: Оба способа работают, так что это вопрос стиля. –

+9

@ DietrichEpp: Хороший ответ, но использование 'super()' не относится к стилю: важно использовать его (вместо использования явного суперкласса) в случае, если ваш собственный класс является подклассом. Пример ссылки: http://rhettinger.wordpress.com/2011/05/26/super-considered-super/. Кроме того, использование 'super()' упрощает управление кодом (проще изменить название класса). – EOL