假设我有这门课:

class Foo:
    @classmethod
    def some_decorator(cls, ...):
        ...

然后我创建了一个使用父类decorator的子类:
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条。准备类命名空间
一旦确定了适当的元类,那么
已准备命名空间。如果元类具有__prepare__属性,
它被称为namespace = metaclass.__prepare__(name, bases, **kwds)
(如果其他关键字参数(如果有)来自类
定义)。
简单地说:您让__prepare__方法返回一个字典,其中包含decorator的条目。概念证明:

class MyMeta(type):
    def __prepare__(name, bases):
        return {'x': 'foobar'}

class MyClass(metaclass=MyMeta):
    print(x)  # output: foobar

关于python - Python-在类声明中访问父类装饰器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55190574/

10-12 21:03