#python #regex
#python #регулярное выражение
Вопрос:
У меня есть базовый класс и несколько подклассов. Каждый подкласс имеет атрибут с именем «регулярное выражение», содержащий строку:
# module level dictionary
action_types = {}
class Action():
regex = '.*'
@classmethod
def register_action(cls):
action_types[cls.regex] = cls
class Sing(Action):
regex = r'^SING [0-9] '
Sing.register_action()
class Dance(Action):
regex = r'^DANCE [0-9] '
Dance.register_action()
Я хочу зарегистрировать все подклассы в словаре action_types, используя регулярное выражение каждого класса в качестве ключа. Я хочу, чтобы логика регистрации класса была ограничена базовым классом.
Приведенный выше пример не работает, и я полагаю, это связано с тем, что переменные Dance и Sing еще недоступны в пространстве имен, когда они используются.
Есть ли какой-либо способ зарегистрировать подклассы в словаре во время инициализации класса?
Комментарии:
1. Почему вы используете для этого отдельные классы? Что плохого в том, чтобы сделать регулярное выражение членом экземпляра и экземплярами Sing, Dance и т. Д.?
2. На практике я хочу, чтобы классы Sing и Dance имели уникальные функции инициализации . Я думаю, что использование шаблона метакласса, как в примере, представленном Игнасио, на самом деле обеспечивает лучшее из обоих миров — подклассы являются экземплярами, но также могут иметь уникальные функции инициализации.
Ответ №1:
Это не то, как вы хотите это сделать.
class ActionRegistry(type):
registry = {}
def __init__(cls, name, bases, dic):
if 'regex' in dic:
cls.registry[dic['regex']] = cls
super(ActionRegistry, cls).__init__(name, bases, dic)
class Action(object):
__metaclass__ = ActionRegistry
class Sing(Action):
regex = r'^SING [0-9] '
class Dance(Action):
regex = r'^DANCE [0-9] '
Ответ №2:
Это работает:
action_types = {}
class Action():
regex = '.*'
@classmethod
def register_action(cls):
action_types[cls.regex] = cls
class Sing(Action):
regex = r'^SING [0-9] '
Sing.register_action()
class Dance(Action):
regex = r'^DANCE [0-9] '
Dance.register_action()
Ответ №3:
Не пытайтесь делать это во время инициализации класса.
Вот более простой способ сделать это:
action_types = {}
class Action():
regex = '.*'
class Sing(Action):
regex = r'^SING [0-9] '
class Dance(Action):
regex = r'^DANCE [0-9] '
def register_action(cls):
action_types[cls.regex] = cls
for cls in (Sing, Dance):
register_action(cls)