Я заглянул внутрь библиотеки, о которой вы говорите, и класс Lexer
наследует метакласс:
class Lexer(metaclass=LexerMeta):
Внутри LexerMeta
вы можете найти следующее:
@classmethod
def __prepare__(meta, name, bases):
d = LexerMetaDict()
def _(pattern, *extra):
patterns = [pattern, *extra]
def decorate(func):
pattern = '|'.join(f'({pat})' for pat in patterns )
if hasattr(func, 'pattern'):
func.pattern = pattern + '|' + func.pattern
else:
func.pattern = pattern
return func
return decorate
d['_'] = _
d['before'] = _Before
return d
Метакласс используется для создания объекта класса, который затем используется для создания экземпляров объектов. Из того, что я вижу в этом методе, можно сказать, что здесь d['_'] = _
этот метакласс динамически присоединяет метод _
к классу, который вы собираетесь использовать.
Это означает, что то, что они делают, мало чем отличается от:
class Bar:
@staticmethod
def some_decorator(f):
...
@some_decorator
def some_function(self):
...