Python-在类声明中访问父类装饰器 [英] Python - Accessing parent class decorators inside class declaration

查看:102
本文介绍了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



请参阅示例:

 来自sly import Lexer ,解析器

类CalcLexer(Lexer):
...

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

...

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



他们是如何做到的?

解决方案

这是通过完成的实现 hon.org/3/reference/datamodel.html#preparing-the-class-namespace rel = nofollow noreferrer> __ 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 as namespace = 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆