本文介绍了Python-在类声明中访问父类装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这个课程:

  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 import Lexer ,解析器

类CalcLexer(Lexer):
...

@_(r'\d +')
def NUMBER(self, t):
t.value = int(t.value)
return t

...

如您所见,您可以输入 @_(...)而不是 @Lexer ._(...)



他们是如何做到的?

解决方案

这是通过方法。来自文档的摘录:

简单地说:您使 __ 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:

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-在类声明中访问父类装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 19:43