Вопрос по python, subclass, ordereddictionary, inheritance – Как создать подкласс OrderedDict?
Подклассы 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?
Вы должны призватьOrderedDict.__init__
от твоего__init__
:
class OrdDictSub(collections.OrderedDict):
def __init__(self):
super(OrdDictSub, self).__init__()
Вы не далиOrderedDict
шанс инициализировать себя. Технически, вы хотите сделать это для вашегоdict
подкласс, так как вы хотите полностью инициализированdict
, Дело в том, чтоdict
работает без этого просто удача.
Попробуйте инициализировать суперкласс в__init__
метод:
def __init__(self):
collections.OrderedDict.__init__(self)
self[1] = 10
Это нормальный способ инициализации подкласса. Вы не используетеhave позвонить суперклассу__init__
метод в целом, но если вы не знаете о реализации суперкласса, вам действительно следует вызвать__init__
.
super()
это путь, но я не согласен с вашим "более того": я бы сказал, что это шесть из полутора десятков других,in Python 2, Если вы хотите изменить имя вашегоOrdDictSub
класс, но по-прежнему оставляют того же родителя, а затемsuper()
означает, что вы должны сделать это в двух местах, а не в одном. С другой стороны, если вы хотите сохранитьOrdDictSub
имя, но изменить родителя, тоnot с помощьюsuper()
означает, что вы должны сделать это в двух местах, а не в одном. К счастью, это было исправлено в Python 3 (просто позвонитеsuper()
без параметров).
super()
это не вопрос стиля: важно использовать его (вместо использования явного суперкласса) в случае, если ваш собственный класс находится в подклассе. Пример справки:rhettinger.wordpress.com/2011/05/26/super-considered-super, Кроме того, используяsuper()
упрощает поддержку кода (проще изменить имя класса).
Eric O Lebigot