2016-04-19 2 views
0

Я попытался унаследовать от обоих collections.defaultdict и collections.OrderedDict как так:Наследование от defaultddict и OrderedDict

class OrderedDefaultDict(defaultdict, OrderedDict): pass 

и вот так:

class OrderedDefaultDict(OrderedDict, defaultdict): pass 

для того, чтобы созданный упорядоченный Dict по умолчанию (класс, должен помнить порядок, в котором были созданы новые элементы по умолчанию), но, похоже, выдает сообщение об ошибке:

TypeError: multiple bases have instance lay-out conflict 

Я прочитал here, что это потому, что они оба реализованы в C. После отключения реализации языка Python C из OrderedDict, комментируя этот раздел в collections модуле:

try: 
    from _collections import OrderedDict 
except ImportError: 
    # Leave the pure Python version in place. 
    pass 

Я сумел наследовать от обоих, но он не работает так, как я ожидал. У меня есть два вопроса:

  1. Почему вы не можете наследовать от двух классов, написанных на C? Я бы понял, если вы не сможете наследовать ни один класс, написанный на C, но почему вы можете наследовать один, а не 2?
  2. Выполнение моего запрошенного класса было бы легко путем подкласса OrderedDict и переопределения __getitem__() в соответствии с поведением defaultdict. Есть ли лучший способ (желательно в стандартной библиотеке), чтобы имитировать такое же поведение? Или является подклассом OrderedDict наиболее оптимальным? (Подклассов defaultdict возможно тоже, но его реализация является, вероятно, легче с помощью OrderedDict)

Первый вопрос является важным из двух в реализации его сам по подклассов OrderedDict не должно представлять проблему.

+1

Я думаю, вы бы лучше подклассы 'OrderedDict' и определения [' __missing__'] (https: // документы .python.org/2/reference/datamodel.html # object .__ missing__). –

+0

Я думаю, что если ваше редактирование истинно, то какая «важная часть» вашего вопроса есть, то это дубликат. Вы неправильно поняли ответ, который вы связали. Дело не в том, что они реализованы в C. Дело в том, что они внутренне несовместимы (хотя реализация C делает это более вероятным/вероятным), поэтому Python не может автоматически использовать их для множественного наследования. –

+0

@ Two-BitAlchemist Почему они были бы внутренне несовместимы? Классы в STL обычно разговаривают с собой красиво, например, как «OrderedDict» и «Counter». – Bharel

ответ

2

Функциональность defaultdict может быть просто реализована путем определения __missing__ метода:

class DefaultOrderedDict(OrderedDict): 
    def __init__(self, default_factory=None, **kwargs): 
     OrderedDict.__init__(self, **kwargs) 
     self.default_factory = default_factory 

    def __missing__(self, key): 
     result = self[key] = self.default_factory() 
     return result 
+0

Думаю, я хочу сделать '__init__' немного более надежным, чем это. Таким образом вы теряете много функций 'dict'. –

+0

согласовано. просто используйте '__init__' из defaultdict:' def __init __ (self, default_factory = None, ** kwargs): ' – acushner

+0

@acushner: согласен. – Daniel

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