I have a python program with 2 threads ( let's name them 'source' and 'destination' ). Source thread sometimes post a message to destination thread with some arguments. Than destination thread picks a message it must call a corresponding function with aruments saved in message.
This task can be solved multiple ways. The easy one is tu put a big 'if...if..if' in destination thread's message pick cycle and call function according to received message type and saved arguments. But this will result in huge amounf of code ( or big lookup table ) and adding new messages / handler function will evolve additonal step to write code in message pick cycle.
Since python treats functions as first-class objects and have tuples, i want to put a function and argumens inside a message, so than destination thread picks a message it just call a functon saved within a message without any knowledge what function it is.
I can write a code for a functions with specified number of arguments:
from Queue import *
from thread import *
from time import *
q = Queue()
def HandleMsg( arg1, arg2 ) :
print arg1, arg2
def HandleAnotherMsg( arg1, arg2, arg3 ) :
print arg1, arg2, arg3
def DestinationThread( a ) :
while True :
(f, a, b) = q.get()
f( a, b )
start_new_thread( DestinationThread, ( 0, ) )
print "start"
sleep( 1 )
q.put( (HandleMsg, 1, 2) )
sleep( 1 )
print "stop"
The question is: how to modify a code so i can put() a function with any number of arguments in queue? for example HandleAnotherMsg() ? Using q.put( (HandleAnotherMsg, 1, 2, 3) ) will rise a compilation error :(
Information can be passed into functions as arguments. Arguments are specified after the function name, inside the parentheses. You can add as many arguments as you want, just separate them with a comma.
To extract the number and names of the arguments from a function or function[something] to return ("arg1", "arg2"), we use the inspect module. The given code is written as follows using inspect module to find the parameters inside the functions a Method and foo.
from Queue import *
from thread import *
from time import *
q = Queue()
def HandleMsg( arg1, arg2 ) :
print arg1, arg2
def HandleAnotherMsg( arg1, arg2, arg3 ) :
print arg1, arg2, arg3
def DestinationThread() :
while True :
f, args = q.get()
f(*args)
start_new_thread( DestinationThread, tuple() )
print "start"
sleep( 1 )
q.put( (HandleMsg, [1, 2]) )
sleep( 1 )
q.put( (HandleAnotherMsg, [1, 2, 3]) )
sleep( 1 )
print "stop"
So simple:
def DestinationThread( a ) :
while True :
items = q.get()
func = items[0]
args = items[1:]
func(*args)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With