什么时候调用 class 装饰器?
When is a class decorator called?
我正在使用节 NLP 库,它使用装饰器来注册处理器。 Stanza 有一个用于构建您自己的处理器的帮助页面 here
他们使用 class 装饰器 @register_processor("processor_name")
。 register_processor
的代码看起来非常简单。它将处理器的名称放在字典中作为键,class 作为值。
我不清楚装饰器或附加到该装饰器的函数何时被调用。它是在 class 初始化之前调用还是在其他某个时候调用?
我确实尝试 Google 搜索,我发现了很多关于如何使用装饰器以及何时调用函数装饰器的信息,但我无法轻易地找到关于 class 装饰器的具体答案。
正如@jonrsharpe 所说,它是在构建 class 之后调用的。这是一个类似装饰器的例子。 (注意 register_class
函数实际上如何 returns 一个特定的内部函数;这是 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'>}
我正在使用节 NLP 库,它使用装饰器来注册处理器。 Stanza 有一个用于构建您自己的处理器的帮助页面 here
他们使用 class 装饰器 @register_processor("processor_name")
。 register_processor
的代码看起来非常简单。它将处理器的名称放在字典中作为键,class 作为值。
我不清楚装饰器或附加到该装饰器的函数何时被调用。它是在 class 初始化之前调用还是在其他某个时候调用?
我确实尝试 Google 搜索,我发现了很多关于如何使用装饰器以及何时调用函数装饰器的信息,但我无法轻易地找到关于 class 装饰器的具体答案。
正如@jonrsharpe 所说,它是在构建 class 之后调用的。这是一个类似装饰器的例子。 (注意 register_class
函数实际上如何 returns 一个特定的内部函数;这是 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'>}