Since the exposed properties are class attributes, it makes sense to construct the desired list (of the exposed properties of the class together with those of its ancestors) at the time of class creation, for which you can use a metaclass. (Edit: I see the same suggestion was made in the comments.)
Here's an example of doing that:
class ExposedMeta(type):
def __init__(cls, name, bases, attrs):
if not "exposed_properties" in attrs:
cls.exposed_properties = []
all_props = set(cls.exposed_properties)
for base in bases:
all_props.update(getattr(base, "all_exposed_properties", []))
cls.all_exposed_properties = list(all_props)
super(ExposedMeta, cls).__init__(name, bases, attrs)
class A(object):
__metaclass__ = ExposedMeta
exposed_properties = ['A1', 'A2']
class B(A):
exposed_properties = ['B']
class C(A):
pass
class D(object):
__metaclass__ = ExposedMeta
exposed_properties = ['D']
class E(B, D):
exposed_properties = ['E1', 'E2']
for cls in [A, B, C, D, E]:
print "Class %s, exposed: %s, all exposed: %s" % (cls.__name__, cls.exposed_properties, cls.all_exposed_properties)