【问题标题】:How to decorate a function and get a class in python如何在python中装饰一个函数并获取一个类
【发布时间】:2022-01-21 22:12:17
【问题描述】:

我正在尝试装饰一个函数并让装饰器将其转换为一个类。

我目前有这样的课程:

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

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

我试着装饰它,让它看起来更好看:

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

这是我当前不起作用的装饰器代码:

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

有没有办法做到这一点?

【问题讨论】:

  • 你的意思是不工作...?另外,如果你装饰一个函数,你返回的应该仍然是一个函数,或者至少是一个 callable 对象,BaseCore 是否实现了__call__? IE。 BaseCore 实例是否可调用?如果没有,这没有多大意义。
  • 我收到了topics = topics NameError: name 'topics' is not defined。但是没有 - BaseCore 没有实现。
  • NewCore.run = types.MethodType(lambda cls, topic, payload: func(topic, payload), BaseCore)**没有**。 MethodType 对象不属于该类。它应该只是一个普通的函数对象*,否则它不会工作
  • 除非我将其转换为 MethodType,否则它将无法正常工作(请参阅 pastebin.com/daB1KGc7

标签: python python-3.x python-decorators python-class


【解决方案1】:

你的装饰器应该返回一个接受装饰函数并创建一个类的函数,其run 方法只调用装饰函数。

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

【讨论】:

  • 谢谢。我还用装饰函数中的值覆盖了_.__qualname___.__module__,因为它们在我的项目中非常明显。
  • 我可以做的一件事是使用functools.wrap;我不记得它是否不仅仅是复制名称。
猜你喜欢
  • 1970-01-01
  • 2023-01-16
  • 2019-11-07
  • 2013-11-17
  • 2021-12-26
  • 2011-07-03
  • 2020-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多