假设我有这个类(class):
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
图书馆就是这样做的。
查看他们的示例:
from sly import Lexer, Parser
class CalcLexer(Lexer):
...
@_(r'\d+')
def NUMBER(self, t):
t.value = int(t.value)
return t
...
如您所见,您可以输入 @_(...)
而不是 @Lexer._(...)
。
他们是如何做到这一点的?
最佳答案
这是通过 metaclass 完成的实现了 __prepare__
方法。文档摘录:
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).
简单来说:您让 __prepare__
方法返回一个包含装饰器条目的字典。概念证明:
class MyMeta(type):
def __prepare__(name, bases):
return {'x': 'foobar'}
class MyClass(metaclass=MyMeta):
print(x) # output: foobar
关于Python - 在类声明中访问父类装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55190574/