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
The motivation for this is that I'm trying to use the Thespian troupe code "as-is".
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.
The module is calculator.calculator (yes, bad choice perhaps)
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())