'Run class method based on tag

I wanted to run the below class functions based on tag name provided at run time

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")

Expectation:

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"


Solution 1:[1]

While I agree with @a_guest that it seems like a messy code design, I managed to come up with what I think is a decent solution for actual decorators.

Create a Tag class that can be initialized with a string for the tag and can be called to return a decorator that will tag a function that it decorates with string used for __init__.

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

Now the weird part - class decorator that looks up all the methods marked with tag and adds the attribute to the class with name of a tag and value being the method.

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

The class that will use tags need to be marked with the class decorator and method has to be marked with call to method decorator.

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

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 matszwecja