Python-在类声明中访问父类装饰器 [英] Python - Accessing parent class decorators inside class declaration
问题描述
class Foo:
@classmethod
def some_decorator( cls,...):
...
然后创建一个子类使用父类装饰器:
class Bar(Foo):
@ Foo.some_decorator(...)
def some_function(...)
...
如何删除在装饰器名称之前是否需要 Foo。
?下面的代码不起作用:
class Bar(Foo):
@some_decorator(...)
def some_function(...)
...
我相信这是可能是因为 sly
库
请参阅示例:
来自sly import Lexer ,解析器
类CalcLexer(Lexer):
...
@_(r'\d +')
def NUMBER(self, t):
t.value = int(t.value)
return t
...
如您所见,您可以输入 @_(...)
而不是 @Lexer ._(...)
。
他们是如何做到的?
这是通过完成的实现 __ prepare __
3.3.3.4。准备类名称空间
一旦标识了适当的元类,则准备类
命名空间。如果元类具有__ prepare __
属性,则
称为namespace = metaclass .__ prepare __(name,bases,** kwds)
(其中其他关键字参数(如果有的话)来自类
的定义)。
简单地说:您使 __ prepare __
方法返回一个字典,其中包含装饰器的条目。概念证明:
class MyMeta(type):
def __prepare __(name,bases):
返回{'x':'foobar'}
class MyClass(metaclass = MyMeta):
print(x)#输出:foobar
Let's say I have this class:
class Foo:
@classmethod
def some_decorator(cls, ...):
...
And then I create a subclass which uses the parent class decorator:
class Bar(Foo):
@Foo.some_decorator(...)
def some_function(...)
...
How do I remove the need for Foo.
before the decorator name? The below code doesn't work:
class Bar(Foo):
@some_decorator(...)
def some_function(...)
...
I believe this is possible, because the sly
library does this.
See their example:
from sly import Lexer, Parser
class CalcLexer(Lexer):
...
@_(r'\d+')
def NUMBER(self, t):
t.value = int(t.value)
return t
...
As you can see, you can type in @_(...)
instead of @Lexer._(...)
.
How do they accomplish this?
This is done with a metaclass that implements a __prepare__
method. Excerpt from the docs:
3.3.3.4. Preparing the class namespace
Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a
__prepare__
attribute, it is called asnamespace = metaclass.__prepare__(name, bases, **kwds)
(where the additional keyword arguments, if any, come from the class definition).
To put it in simple terms: You make your __prepare__
method return a dictionary that contains an entry for the decorator. Proof of concept:
class MyMeta(type):
def __prepare__(name, bases):
return {'x': 'foobar'}
class MyClass(metaclass=MyMeta):
print(x) # output: foobar
这篇关于Python-在类声明中访问父类装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!