Python class hierarchy, extend ancestor data I have a hierarchy of entities that should contain dictionaries with metadata. Any sub-class should inherit its ancestor dictionary and be able to add some key-values (delete inherit keys is not needed). The easiest solution I can think about is this:

class A(object):
    def __init__(self):
        self.doc = A.generate_doc()

    @staticmethod
    def generate_doc():
         return {'a': 0}

class B(A):
    def __init__(self):
        super().__init__()
        self.doc.update(B.generate_doc())

    @staticmethod
    def generate_doc():
        return {'b': 0}

class C(B):
    def __init__(self):
        super().__init__()
        self.doc.update(C.generate_doc())

    @staticmethod
    def generate_doc():
        return {'c': 0}

print(A().doc)  # {'a': 0}
print(B().doc)  # {'a': 0, 'b': 0}
print(C().doc)  # {'a': 0, 'b': 0, 'c': 0}


Is this a good design? Could the update() blocks be implicit maybe? I have more than one document in real code, so that would be nice.
Is this a good design?


No IMO it's quite horrible, please reconsider it.


  Could the update() blocks be implicit maybe?


Yeah, use metaclasses.


  I have more than one document in real code, so that would be nice.


Yeah, don't request us to write code for you. However, with a metaclass this is easy.



To make a cross Python 2 and Python 3 metaclass you need to use something like Class = Class('name', (object,), {}).
You want to also build these dictionaries in the metaclasses __new__, and for the values to be taken from another attribute.
To do this I defaulted to the uppercase of the value. I.e. A.DOC.

This works kinda like Python's default multiple inheritance, but I make no guarantees. Also doc is now a static value, so you may need to clone it at object instantiation.

def update(values=[]):
    if isinstance(values, str):
        values = values.split()
    class Meta(type):
        def __new__(meta, classname, bases, class_dict):
            for value in values:
                val = {}
                for base in reversed(bases):
                    val.update(getattr(base, value, {}))
                val.update(class_dict.get(value.upper(), {}))
                class_dict[value] = val
            return super(Meta, meta).__new__(meta, classname, bases, class_dict)
    return Meta('Meta', (object,), {})


class A(update('doc')):
    DOC = {'v': 0}

class B(A):
    DOC = {'v': 1}

class C(A):
    DOC = {'c': 0}

class D(B, C):
    pass

class E(C, B):
    pass

print(D.doc)
print(E.doc)