I would like to define properties for classes, and be able to access them before I actually instantiate an object of that class.
I'll give some context. My application handles a library of components. Each component is mapped to a Python class. Now I want to know what configuration a component needs, before actually instancing the class.
One solution is to write something like this:
class Component:
@classmethod
def config(cls, name, description, default=None):
''' Define one configuration switch for the class. '''
# now put this information in a class-specific dictionary
class Model1(Component):
@classmethod
def define_configuration(cls):
cls.config('n', 'number of burzs to instigate')
cls.config('skip', 'skip any barzs among the burzs', default=True)
# ...
component_class = Model1
component_class.define_configuration()
However, it seems pretty ugly. Ideally I would like to be able to write something like the following, and still be able to put the configuration switches in a class-specific dictionary to be accessed later.
class Model1(Component):
config('n', 'number of burz to instigate')
config('skip', 'skip any barz in the data', default=True)
My initial solution was to write something like:
class Model1(Component):
Model1.config('n', 'number of burz to instigate')
Model1.config('skip', 'skip any barz in the data', default=True)
however I discovered on other questions here on SO that the class name is not defined yet when the body is executed.
What should I do?
tl;dr: How can I get a nice syntax for defining class-specific properties (before I instance an object of that class)?
Here is (for the record) the solution that was suggested (a bit elaborated). Yai! I could get exactly what I wanted. :-)
from collections import namedtuple
Config = namedtuple('Config', 'name desc default')
def config(name, description, default=None):
ComponentMeta.tmp_config_storage.append(Config(name, description, default))
class ComponentMeta(type):
tmp_config_storage = []
def __init__(cls, clsname, bases, clsdict):
for config in ComponentMeta.tmp_config_storage:
if not 'my_config' in cls.__dict__:
setattr(cls, 'my_config', [])
cls.my_config.append(config)
ComponentMeta.tmp_config_storage = []
class Component(object):
__metaclass__ = ComponentMeta
class Model1(Component):
config('x1', 'for model1')
config('y1', 'for model1')
class Model2(Component):
config('x2', 'for model2')
print 'config for Model1:', Model1.my_config
print 'config for Model2:', Model2.my_config