在函数中定义一个类以中断装饰器的执行

时间:2019-04-15 21:22:09

标签: python python-decorators

我正在尝试在运行时配置装饰器。这与我之前的问题有关:How to configure a decorator in Python

这样做的动机是我试图使用Thespian剧团代码“按原样”。

在这里在我已经在类方法中定义了类(因此称为装饰器)的地方使用此代码合法吗?同样,这样做的原因是我可以在调用装饰器之前输入max_count参数。

模块是Calculator.calculator(是的,也许是错误的选择)

class Scheduler:
    def __init__(self):
        self.actor_system = None

    def start(self):
        self.actor_system = ActorSystem('multiprocTCPBase')

    def stop(self):
        self.actor_system.shutdown()

    def launch(self, count, func_and_data, status_cb):
        class CalcPayload:
            def __init__(self, func_and_data, status_cb):
                self.func_and_data = func_and_data
                self.status_cb = status_cb

        @troupe(max_count=count)
        class Execute(ActorTypeDispatcher):
            def receiveMsg_CalcPayload(self, msg, sender):
                func = msg.func_and_data['func']
                data = msg.func_and_data['data']
                status_cb = msg.status_cb

                self.send(sender, func(data, status_cb))

        exec_actor = self.actor_system.createActor(Execute)

        for index in range(len(func_and_data)):
            calc_config = CalcPayload(func_and_data[index], status_cb)
            self.actor_system.tell(exec_actor, calc_config)

        for index in range(len(func_and_data)):
            result = self.actor_system.listen(timeout)

        self.actor_system.tell(exec_actor, ActorExitRequest())

由于各种原因,使用装饰器时无法将其应用于类。在我提到的问题中对此进行了简短的讨论。

2 个答案:

答案 0 :(得分:1)

虽然不是无效的,但通常不建议将类定义为函数内部的局部变量,因为这样会使在函数外部访问该类变得困难。

相反,您可以在函数外部定义类,并在实际需要时通过将装饰器函数与类对象一起调用,将装饰器函数应用于该类:

class CalcPayload:
    def __init__(self, func_and_data, status_cb):
        self.func_and_data = func_and_data
        self.status_cb = status_cb


class Execute(ActorTypeDispatcher):
    def receiveMsg_CalcPayload(self, msg, sender):
        func = msg.func_and_data['func']
        data = msg.func_and_data['data']
        status_cb = msg.status_cb

        self.send(sender, func(data, status_cb))

class Scheduler:
    def __init__(self):
        self.actor_system = None

    def start(self):
        self.actor_system = ActorSystem('multiprocTCPBase')

    def stop(self):
        self.actor_system.shutdown()

    def launch(self, count, func_and_data, status_cb):
        exec_actor = self.actor_system.createActor(troupe(max_count=count)(Execute))

        for index in range(len(func_and_data)):
            calc_config = CalcPayload(func_and_data[index], status_cb)
            self.actor_system.tell(exec_actor, calc_config)

        for index in range(len(func_and_data)):
            result = self.actor_system.listen(timeout)

        self.actor_system.tell(exec_actor, ActorExitRequest())

答案 1 :(得分:1)

actor_system将要构建您的类的实例。这意味着它需要能够派生类对象-您不能在方法内部定义它。

如果您确实需要单独应用装饰器,则可以这样做

def launch(self, count, func_and_data, status_cb):
    wrapped = troupe(max_count=count)(Executor)
    exec_actor = self.actor_system.createActor(wrapped)