Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure a decorator in Python

I'm trying to use Thespian (https://thespianpy.com/doc/), a Python library for the actor model, and in particular I'm trying to use the "troupe" functionality. As I understand it, the troupe decorator acts as a scheduler to run multiple actors up to the max_count specified, with each actor running in parallel. The troupe functionality is applied as a decorator on my actor class:

@troupe(max_count = 4, idle_count = 2)
class Calculation(ActorTypeDispatcher):
    def receiveMsg_CalcMsg(self, msg, sender):
        self.send(sender, long_process(msg.index, msg.value, msg.status_cb))

I would like to configure max_count at run time, instead of design time. I'll admit my base knowledge on decorators is weak.

How can I pass a value to max_count at run time?

I have gone through these, but I'm still in the dark:

Does python allow me to pass dynamic variables to a decorator at runtime?

http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/

Per the answers so far, I attempted this, but the decorator was not being applied (i.e. it acted as if there were no decorator). I commented out the @troupe implementation above the class, that method (including with the variable) is working fine. This approach isn't:

# @troupe(max_count=cores, idle_count=2)
class Calculation(ActorTypeDispatcher):
    def receiveMsg_CalcMsg(self, msg, sender):
        self.send(sender, long_process(msg.index, msg.value, msg.status_cb))

def calculate(asys, calc_values, status_cb):
    decorated_class = troupe(max_count=5, idle_count=2)(Calculation)
    calc_actor = asys.createActor(decorated_class)

There is other stuff in the calculate function, but that is pretty much just some book keeping.

like image 573
Brian Avatar asked Apr 15 '19 14:04

Brian


2 Answers

Decorator syntax is just a shortcut for applying a function to a class. You can make that function call yourself once you know the value for max_count.

class Calculation(ActorTypeDispatcher):
    ...

# Time passes

c = input("Max count: ")
Calculation = troupe(max_count=int(c), idle_count=2)(Calculation)

(or, simply wait until you do have c before defining Calculation, as shown by @brunns.)

like image 154
chepner Avatar answered Oct 06 '22 10:10

chepner


Should be as simple as:


my_max = get_max_from_config_or_wherever()

@troupe(max_count = my_max, idle_count = 2)
class Calculation(ActorTypeDispatcher):
    ...

Thing to remember is that class and def statements are themselves executed.

like image 31
brunns Avatar answered Oct 06 '22 12:10

brunns