Reputation: 675
Let's say I have the following class hierarchy:
class A(object):
_d = {}
class B(A):
_d = {'b': 1}
class C(A):
_d = {'b': 2, 'c': 3}
class D(B):
_d = {'d': 4}
Is there a way to write an @property method d
on A
which will return the aggregated dictionary over all superclasses of an object? For example, B().d
would return {'b': 1}
, C().d
would return {'b': 2, 'c': 3}
, and D().d
would return {'b': 1, 'd': 4}
.
Upvotes: 1
Views: 463
Reputation: 71004
Use inspect.getmro
to skip any concerns with multiple inheritance and avoid the necessity of a recursive call to get all the subclasses.
import inspect
@property
d(self):
res = {}
subclasses = inspect.getmro(type(self))
for cls in reversed(subclasses):
res.update(gettattr(cls, 'd', {}))
return res
Upvotes: 4
Reputation: 304147
@property
def d(self):
res = dict(self._d)
for c in self.__class__.__bases__:
res.update(getattr(c(),'d',{}))
return res
Upvotes: 2
Reputation: 11315
Well, straightforward solution is to use __bases__
attribute of the class to traverse inheritance chain. However there are some multiple inheritance issues which may or may not to be a concern for you.
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}
Upvotes: 2