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

问题描述 投票:2回答:2

我正在尝试在运行时配置装饰器。这与我之前的问题有点相关: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())

由于各种原因,我在使用它时不能将装饰器应用于类。在我引用的问题中对此进行了简短的讨论。

python python-decorators
2个回答
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
投票

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

如果你真的需要单独应用装饰器,你可能会这样做

def launch(self, count, func_and_data, status_cb):
    wrapped = troupe(max_count=count)(Executor)
    exec_actor = self.actor_system.createActor(wrapped)
© www.soinside.com 2019 - 2024. All rights reserved.