我有一个包含2个线程的python程序(让我们将它们命名为'source'和'destination').源线程有时会使用一些参数将消息发布到目标线程.比目标线程选择一条消息,它必须使用保存在消息中的历史记录调用相应的函数.
这个任务可以通过多种方式解决.容易的是在目标线程的消息选择周期中调整一个大的'if ... if..if'并根据收到的消息类型和保存的参数调用函数.但这将导致巨大的代码(或大查找表),并且添加新的消息/处理函数将演变为在消息选择周期中编写代码的额外步骤.
由于python将函数视为第一类对象并具有元组,因此我想在消息中放置函数和参数,因此,目标线程选择一条消息,它只是调用保存在消息中的函数,而不知道它是什么函数.
我可以为具有指定数量的参数的函数编写代码:
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"
问题是:如何修改代码,以便我可以把()一个函数与队列中的任意数量的参数放在一起?例如HandleAnotherMsg()?使用q.put((HandleAnotherMsg,1,2,3))会出现编译错误:(
很简单:
def DestinationThread( a ) : while True : items = q.get() func = items[0] args = items[1:] func(*args)
另一个有趣的选择就是传入一个lambda.
q.put(lambda: HandleMsg(1,2)) q.put(lambda: HandleAnother(8, "hello", extra="foo")) def DestinationThread() : while True : f = q.get() f()
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"