Я использую библиотеку stanza NLP, которая использует декоратор для регистрации процессоров. У Stanza есть страница справки для создания собственных процессоров здесь
Они используют декоратор класса @register_processor("processor_name")
. Код для register_processor
выглядит довольно просто. Он помещает имя процессора в словарь в качестве ключа и класс в качестве значения.
Мне неясно, когда вызывается декоратор или функция, прикрепленная к этому декоратору. Вызывается ли он непосредственно перед инициализированным классом или в какой-то другой момент?
Я пробовал поиск в Google, я нашел много о том, как использовать декораторы и когда вызываются декораторы функций, но я не смог легко найти этот конкретный ответ на декораторах классов.
Ах, кажется, я сделал ложное предположение. Init не является конструктором (stackoverflow.com/questions/6578487/init-как-конструктор). Простой импорт класса в мой модуль приводит к его «созданию», и перед инициализацией вызывается декоратор. Это правильно?
Он вызывается, когда этот модуль загружается, обычно в результате (первого) импорта, да. Именно тогда запускается код верхнего уровня, включая определения классов и функций.
Как сказал @jonrsharpe, он вызывается после создания класса. Вот пример подобного декоратора. (Обратите внимание, что функция register_class
на самом деле возвращает определенную внутреннюю функцию; это общий шаблон для любого декоратора в Python.)
registry = {}
def register_class(name):
def decorator(cls):
registry[name] = cls
print(f"Registered {name}: {cls}")
return cls
return decorator
print("Hello!")
@register_class("foo")
class Bloop:
pass
print(f"Hi there! We have {registry} in the house.")
@register_class("another")
class Else:
pass
print(f"Whew, that's a lot of classes! {registry}")
Это распечатывает
Hello!
Registered foo: <class '__main__.Bloop'>
Hi there! We have {'foo': <class '__main__.Bloop'>} in the house.
Registered another: <class '__main__.Else'>
Whew, that's a lot of classes! {'foo': <class '__main__.Bloop'>, 'another': <class '__main__.Else'>}
Для тех, кто ищет ссылки на официальную документацию: смотрите описания декораторов для определений классов и для определения функций.
Он вызывается сразу после создания самого класса, с класса (точно так же, как декоратор функции вызывается сразу после создания функции вместе с функцией).