I want to keep a dictionary of (all, non-immediate included) subclasses in a base class, so that I can instantiate them from a string. I'm doing this because the CLSID
is sent through a web form, so I want to restrict the choices to the ones set from the subclasses. (I don't want to eval()
/globals()
the classname).
class BaseClass(object):
CLSID = 'base'
CLASSES = {}
def from_string(str):
return CLASSES[str]()
class Foo(BaseClass):
CLSID = 'foo'
BaseClass.CLASSES[CLSID] = Foo
class Bar(BaseClass):
CLSID = 'bar'
BaseClass.CLASSES[CLSID] = Bar
That obviously doesnt work. But is there something like a @classmethod
for init? The idea is that this classmethod would only run once as each class is read and register the class with the baseclass. Something like the following could then work: (Would also save the extra line in Foo
and Bar
)
class BaseClass(object):
CLSID = 'base'
CLASSES = {}
@classmethod
def __init__(cls):
BaseClass.CLASSES[cls.CLSID] = cls
def from_string(str):
return CLASSES[str]()
I thought about using __subclasses__
and then filter()
on CLSID
, but that only works for immediate subclasses.
So, hoping that I explained my purpose, the question is how to make this work? Or am I going about this in a completely wrong way?