如何在类层次结构(Python)上聚合字典

如何在类层次结构(Python)上聚合字典,python,inheritance,dictionary,Python,Inheritance,Dictionary,假设我有以下类层次结构: class A(object): _d = {} class B(A): _d = {'b': 1} class C(A): _d = {'b': 2, 'c': 3} class D(B): _d = {'d': 4} 是否有一种方法可以在a上编写@property方法d,该方法将返回对象所有超类的聚合字典?例如,B().d将返回{'B':1},C().d将返回{'B':2,'C':3},而d().d将返回{'B':1,'d':4}好的,简单的

假设我有以下类层次结构:

class A(object):
  _d = {}

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

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

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

是否有一种方法可以在
a
上编写@property方法
d
,该方法将返回对象所有超类的聚合字典?例如,
B().d
将返回
{'B':1}
C().d
将返回
{'B':2,'C':3}
,而
d().d
将返回
{'B':1,'d':4}
好的,简单的解决方案是使用类的
\uu基类的属性来遍历继承链。然而,有一些多重继承的问题,这可能是你关心的,也可能不是

 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}

简单的解决方法是使用类的
\uuuu base\uuu
属性来遍历继承链。然而,有一些多重继承的问题,这可能是你关心的,也可能不是

 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}

使用
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 

使用
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 

谢谢-inspect.getmro很好了解,但实际上我想用另一种方式来做这件事-从子类中找到超类dict。@rfrankel,现在给出的答案都不是你想要的。它们都接受一个子类,并以某种方式遍历树的某些部分,返回到超类。事实上,你的例子是在一个子类上调用的。这就是我想要的——我的道歉;我想我误解了您的示例(标识符“subclass”让我很反感)。谢谢-inspect.getmro很好,但实际上我想用另一种方式来做这件事-从子类中找到超类dict。@rfrankel,给出的答案都不是您想要的。它们都接受一个子类,并以某种方式遍历树的某些部分,返回到超类。事实上,你的例子是在一个子类上调用的。这就是我想要的——我的道歉;我想我误解了你的例子(标识符“subclass”让我很反感)。