Search code examples
pythonpython-3.xpython-decoratorspython-class

How to decorate a function and get a class in python


I am trying to decorate a function and make the decorator convert it into a class.

I currently have a class like this:

class Licht(BaseCore):
    topics = ["glados/tcs/licht/set"]

    @classmethod
    def run(cls, topic, payload):
        mqtt_publish("tcs/bus/cmd", "1200")

and I try to decorate it, so that it looks nicer:

@core_factory(["glados/tcs/licht/set"])
def Licht(topic, payload):
    mqtt_publish("tcs/bus/cmd", "1200")

This is my current decorator code which doesn't work:

def core_factory(topics):
    class NewCore(BaseCore):
        topics = topics
    def inner(func):
        import types
        NewCore.run = types.MethodType(lambda cls, topic, payload: func(topic, payload), BaseCore)
        return NewCore
    return inner

Is there a way to achieve this?


Solution

  • Your decorator should return a function that takes the decorated function and creates a class whose run method just calls the decorated function.

    def core_factory(topics):
        def wrapper(f):
    
            class _(BaseCore):
                @classmethod
                def run(cls, topic, payload):
                    return f(topic, payload)
    
            _.topics = topics
            _.__name__ = f.__name__
    
            return _
        return wrapper
    
    @core_factory(["glados/tcs/licht/set"])
    def Licht(topic, payload):
        mqtt_publish("tcs/bus/cmd", "1200")