-4

I have existing classes which inherit from each other…they already have a attribute which is being overridden in subclasses . I want the dictionary attribute to be updated instead of overridden…code below …

class A:
  d = {1:2}

class B(A):
  d = {3:4}


b=B()

print b.d[1]
2
print b.d[3]
4

Is this possible at all? Say using metaclasses in a way that I can't think of readily.

Serenity
  • 35,289
  • 20
  • 120
  • 115
eskhool
  • 657
  • 1
  • 11
  • 24

3 Answers3

1
class A(object):
    d = {1:2}

class B(A):
    d = {3:4}
    def __init__(self):
        dtemp = self.d
        self.d = A.d.copy()     # warning: shallow
        self.d.update(dtemp)

b=B()
print b.d[1]
# 2
print b.d[3]
# 4
a=A()
print a.d[1]
# 2
print a.d[3]
# KeyError
rerx
  • 1,133
  • 8
  • 19
  • You've understood my question, though I had it wrong…problem is I have a deep class hierarchy and I would like somehow the base init to handle this…so that any subclass can benefit from the additional attributes – eskhool Sep 27 '13 at 11:57
  • Explicit is better than implicit, I'd say. Maybe let A have a method `add_atributes` which is to be called by derived classes. – rerx Sep 27 '13 at 13:59
0

Don't know what exactly you're trying to do here, but looks like collections.ChainMap may come in handy if you're on py3.3+:

from collections import ChainMap
...
dic = ChainMap(B.d, A.d)

Demo:

>>> dic[1]
2
>>> dic[3]
4

Any modification done to either A.d or B.d would reflect in dic

>>> A.d[4] = 5
>>> dic[4]
5

Modifying the dict itself would modify B.d(First dict passed to ChainMap):

>>> dic[6] = 7
>>> B.d
{3: 4, 6: 7}
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
0

Found this based on some of the ideas around:

class B(A): _d = {}

def __init__(self):
    for parent_klass in inspect.getmro(self.__class__):
        _d.update(getattr(parent_klass, 'd', {}))
    _d.update(self.d)
    self.d = _d
eskhool
  • 657
  • 1
  • 11
  • 24