Как я могу объединить словари по иерархии классов (Python) - PullRequest
1 голос
/ 03 ноября 2010

Допустим, у меня есть следующая иерархия классов:

class A(object):
  _d = {}

class B(A):
  _d = {'b': 1}

class C(A):
  _d = {'b': 2, 'c': 3}

class D(B):
  _d = {'d': 4}

Есть ли способ написать метод @property d для A, который будет возвращать агрегированный словарь по всем суперклассам объекта?Например, B().d вернет {'b': 1}, C().d вернет {'b': 2, 'c': 3}, а D().d вернет {'b': 1, 'd': 4}.

Ответы [ 3 ]

4 голосов
/ 03 ноября 2010

Используйте inspect.getmro, чтобы пропустить любые проблемы с множественным наследованием и избежать необходимости рекурсивного вызова для получения всех подклассов.

import inspect

@property
d(self):
    res = {}
    subclasses = inspect.getmro(type(self))
    for cls in reversed(subclasses):
        res.update(gettattr(cls, 'd', {}))
    return res 
2 голосов
/ 03 ноября 2010
  @property
  def d(self):
    res = dict(self._d)
    for c in self.__class__.__bases__:
        res.update(getattr(c(),'d',{}))
    return res
2 голосов
/ 03 ноября 2010

Что ж, простое решение - использовать атрибут __bases__ класса для обхода цепочки наследования. Однако существуют некоторые проблемы множественного наследования, которые могут вызывать или не беспокоить вас.

 def d(self):
     res = {}
     def traverse(cls):
         if hasattr(cls, '_d'):
             for k,v in cls._d.iteritems():
                 res[k]=v
             for basecls in cls.__bases__:
                 traverse(basecls)
     for k,v in self._d.iteritems():
         res[k]=v
     traverse(self.__class__)
     return res

>>> D().d()
{'a': 1, 'c': 4, 'b': 2}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...