Вопрос по python, subclass, ordereddictionary, inheritance – Как создать подкласс OrderedDict?

26

Подклассы Pythondict работает как положено:

>>> 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 атрибут, который предотвращает подклассOrdDictSub вести себя какDictSub подкласс. Зачем? Как можно наследовать от OrderedDict?

Почему отрицательный голос? Eric O Lebigot

Ваш Ответ

2   ответа
34

Вы должны призватьOrderedDict.__init__ от твоего__init__:

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

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

Благодарю. Мой плохой, действительно. Это правда, что на меня повлиял диктат. Я даже задал вопрос про dict некоторое время назад (stackoverflow.com/questions/2033150/…)! Eric O Lebigot
Разве вы не хотите args и kwargs в init?def __init__(self, *args, **kwargs): super(OrdDictSub, self).__init__(*args, **kwargs)
2

Попробуйте инициализировать суперкласс в__init__ метод:

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

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

@JohnY: это отличный ответ Мартин Питерс охватывает это:stackoverflow.com/a/18208725/82294 - если ты думаешь, что Мартейн не прав, иди спорь там.
@astynax: оба способа работают, так что это вопрос стиля.
@EOL: я могу принять этоsuper() это путь, но я не согласен с вашим "более того": я бы сказал, что это шесть из полутора десятков других,in Python 2, Если вы хотите изменить имя вашегоOrdDictSub класс, но по-прежнему оставляют того же родителя, а затемsuper() означает, что вы должны сделать это в двух местах, а не в одном. С другой стороны, если вы хотите сохранитьOrdDictSub имя, но изменить родителя, тоnot с помощьюsuper() означает, что вы должны сделать это в двух местах, а не в одном. К счастью, это было исправлено в Python 3 (просто позвонитеsuper() без параметров).
использованиеsuper() вызывать методы суперкласса
@DietrichEpp: хороший ответ, но с использованиемsuper() это не вопрос стиля: важно использовать его (вместо использования явного суперкласса) в случае, если ваш собственный класс находится в подклассе. Пример справки:rhettinger.wordpress.com/2011/05/26/super-considered-super, Кроме того, используяsuper() упрощает поддержку кода (проще изменить имя класса). Eric O Lebigot

Похожие вопросы