Я хотел бы определить свойства для классов и иметь возможность получить к ним доступ, прежде чем я на самом деле создаю объект этого класса.
Я приведу некоторый контекст.Мое приложение обрабатывает библиотеку компонентов.Каждый компонент сопоставлен с классом Python.Теперь я хочу знать, какая конфигурация нужна компоненту, прежде чем создавать экземпляр класса.
Одно из решений - написать что-то вроде этого:
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()
Однако это выглядит довольно уродливо.В идеале я хотел бы иметь возможность написать что-то вроде следующего, и все же иметь возможность помещать переключатели конфигурации в словарь для конкретного класса, к которому можно будет обращаться позже.
class Model1(Component):
config('n', 'number of burz to instigate')
config('skip', 'skip any barz in the data', default=True)
Моим первоначальным решением было написать что-тонапример:
class Model1(Component):
Model1.config('n', 'number of burz to instigate')
Model1.config('skip', 'skip any barz in the data', default=True)
однако я обнаружил здесь и другие вопросы о SO, что имя класса еще не определено при выполнении тела.
Что мне делать?
tl; dr: Как мне получить хороший синтаксис для определения свойств, специфичных для класса (перед тем, как я создаю экземпляр объекта этого класса)?
Вот (для записи)решение, которое было предложено (немного разработано).Яй!Я мог получить именно то, что хотел.: -)
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