微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

获取一个类的装饰器标记的所有函数

如何解决获取一个类的装饰器标记的所有函数

我正在尝试存储在类中定义的特定 actions

为了减少代码重复,我想使用一个 mixin 类来存储基于装饰器的所有操作。

这个想法是让其他人使用新操作扩展类应该很简单。我特别想避免在源代码中明确列出这些操作(这应该由装饰器处理)。

这是我想出来的。不幸的是,在所有 .actions 列表中,列出了所有类的所有操作。

但是,我想要一个只列出特定类的操作的解决方案。

class ActionMixin:
    actions = []

    @staticmethod
    def action(fun):
        ActionMixin.actions.append(fun)
        return fun


class Human(ActionMixin):
    @ActionMixin.action
    def talk(self):
        pass


class Dog(ActionMixin):
    @ActionMixin.action
    def wuff(self):
        pass


class Cat(ActionMixin):
    @ActionMixin.action
    def miau(self):
        pass


if __name__ == "__main__":
    party = [Human(),Dog()]
    possible_actions = [action for memer in party for action in member.actions]
    # I would like that possible_actions is Now only Human.talk() and Dog.wuff()
    # instead it is 2 times all actions
    print(len(possible_actions))  # == 6

解决方法

我只想在这里写我自己的描述符。所以:

Wrapper

因此,与其从 mixin 继承,不如初始化描述符对象。然后该对象本身可以用作装饰器(class Registry: def __init__(self): self._registered = [] def __call__(self,func): self._registered.append(func) return func def __get__(self,obj,objtype=None): return self._registered class Human: actions = Registry() @actions def talk(self): pass class Dog: actions = Registry() @actions def wuff(self): pass class Cat: actions = Registry() @actions def miau(self): pass 方法!)。

注意,装饰器将是您分配给它的任何名称,并且它将是存储操作的属性的名称。

在 REPL 中:

__call__

编辑:

如果您希望它存在于基类中,则必须更改实现。基本上,使用 In [11]: party = [Human(),Dog()] In [12]: [action for member in party for action in member.actions] Out[12]: [<function __main__.Human.talk(self)>,<function __main__.Dog.wuff(self)>] 来跟踪注册表,不幸的是,我们必须依靠脆弱的 dict 来获取 __qualname__ 中的类:

__call__

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。