简体   繁体   English

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

[英]Defining a class inside a function to interrupt decorator execution

I'm trying to configure a decorator at run time.我正在尝试在运行时配置装饰器。 This is somewhat related to my earlier question: How to configure a decorator in Python这与我之前的问题有些相关: 如何在 Python 中配置装饰器

The motivation for this is that I'm trying to use the Thespian troupe code "as-is".这样做的动机是我试图“按原样”使用 Thespian 剧团代码。

Is it legal to have this code here, where I've defined the class (and therefore called the decorator) inside a class method?在这里使用这段代码是否合法,我在类方法中定义了类(因此称为装饰器)? Again, the reason for this is that I could feed the max_count argument prior to the decorator being call.同样,这样做的原因是我可以在调用装饰器之前提供max_count参数。

The module is calculator.calculator (yes, bad choice perhaps)该模块是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())

For various reasons, I can't apply the decorator to the class when I use it.由于各种原因,我在使用时无法将装饰器应用于类。 There is a brief discussion on this in the question I referenced.在我引用的问题中对此进行了简要讨论。

While not invalid, it is generally inadvisable to define a class as a local variable inside a function, as it would make access to the class difficult outside the function.虽然不是无效的,但通常不建议将类定义为函数内部的局部变量,因为这会使在函数外部难以访问该类。

Instead, you can define the classes outside the function, and apply the decorator function to the class when it's actually needed by calling the decorator function with the class object:相反,您可以在函数外部定义类,并在实际需要时通过使用类对象调用装饰器函数将装饰器函数应用于类:

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

The actor_system is going to want to build instances of your class. actor_system 将要构建您的类的实例。 That means it needs to be able to derive the class object- you cannot define it inside of a method.这意味着它需要能够派生类对象——你不能在方法内部定义它。

If you really need to apply the decorator separately, you maybe could do如果你真的需要单独应用装饰器,你也许可以这样做

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM