运行 class 基于标签的方法

Run class method based on tag

我想 运行 以下 class 函数基于 运行 时间

提供的标签名称
def tag(tag_name):
    def tags_decorator(func):
        func._tag = tag_name
        return func

    return tags_decorator


class ExampleClass:
    @tag('foo')
    def method_a(self):
        print(" method_a foo")

    @tag('bar')
    def method_b(self):
        print(" method_b bar")

    def method_c(self):
        print(" method_c")

期望:

if __name__ == '__main__':
    ec = ExampleClass()
    ec.foo # it should run the method tagged with foo i.e. method_a and should
           # print " method_a foo"

这似乎是一个奇怪的要求,但您可以实施 __getattr__ 来实现它:

class ExampleClass:
    ...

    def __getattr__(self, name):
        for tp in type(self).mro():
            for obj in vars(tp).values():
                if getattr(obj, '_tag', None) == name:
                    return obj(self)
        raise AttributeError(name)

虽然我同意 @a_guest 的观点,它看起来像是一个混乱的代码设计,但我设法想出了我认为对实际装饰器来说是一个不错的解决方案。

创建一个标签 class,它可以用标签的字符串初始化,并且可以调用 return 一个装饰器,该装饰器将标记一个函数,它用用于 [=13 的字符串装饰=].

class Tag:
    def __init__(self, tag):
        self.tag = tag
    def __call__(self):
        def tag(function):
            function.tag = self.tag
            return function
        return tag

现在是奇怪的部分 - class 装饰器查找所有标记有标签的方法并将属性添加到 class 中,标签名称和值是方法。

def TaggedClass(cls):
    methods_to_add = []
    for method in cls.__dict__.values():
        if hasattr(method, "tag"):
            methods_to_add.append((method.tag, method))
    for tag, method in methods_to_add:
        setattr(cls, tag, method)
    return cls

将使用标签的 class 需要用 class 装饰器标记,方法必须用调用方法装饰器标记。

@TaggedClass
class ExampleClass:
    @Tag("foo")()
    def a_method(self):
        print("foo-bar")

if __name__ == '__main__':
    ec = ExampleClass()
    ec.foo()