Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将函数和参数放入python队列?_Python_Multithreading - Fatal编程技术网

如何将函数和参数放入python队列?

如何将函数和参数放入python队列?,python,multithreading,Python,Multithreading,我有一个包含两个线程的python程序(让我们把它们命名为“源代码”和 “目的地”)。源线程有时会向目标发送消息 线程与一些参数。而目标线程则从中拾取一条消息 必须使用消息中保存的aruments调用相应的函数 这项任务可以通过多种方式解决。最简单的是涂放一个大的 目标线程的消息选取周期和调用中的“if…if..if” 根据收到的消息类型和保存的参数执行函数。但是这个 将导致大量代码(或大型查找表)并添加新的 消息/处理程序函数将演变为编写代码的附加步骤 消息选取周期 由于python将函数视为

我有一个包含两个线程的python程序(让我们把它们命名为“源代码”和 “目的地”)。源线程有时会向目标发送消息 线程与一些参数。而目标线程则从中拾取一条消息 必须使用消息中保存的aruments调用相应的函数

这项任务可以通过多种方式解决。最简单的是涂放一个大的 目标线程的消息选取周期和调用中的“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))将导致编译错误:(

为什么不将队列子类化


class MyQueue(Queue):
  # by using *args, you can have a variable number of arguments
  def put(self,*args):
    for arg in args:
       Queue.put(self,arg)
或者,你为什么不列个清单呢


list = [function_obj]
for arg in function_args:
   list.append(arg)
queue.put(list)
很简单:

def DestinationThread( a ) :
  while True :
    items = q.get()
    func = items[0]
    args = items[1:]
    func(*args)

听起来您想使用
apply()
内在函数或其后续函数:

def f(x. y):
   print x+y

args = ( 1, 2 )

apply(f, args)   # old way

f(*args)        # new way

我以前使用过类似的构造:

class Call:
    def __init__(self, fn, *args, **kwargs):
        self.fn = fn
        self.args = args
        self.kwargs = kwargs

    def __call__(self):
        return self.fn(*self.args, **self.kwargs)


x = Call(zip, [0,1], [2,3], [4,5])
然后,您应该能够将x传递给另一个线程并从那里调用它:

x() # returns the same as zip([0,1], [2,3], [4,5])

您可以使用run方法创建一个抽象消息类。然后,对于需要通过队列传输的每个函数,将该函数作为run方法进行子类化并实现。 发送线程将创建适当子类的实例并将其放入队列中。接收线程将从队列中获取对象并盲目执行run方法

这通常被称为命令模式(Gamma等人)

例如:

class Message (object):
    """abstract message class"""
    def __init__(self, **kwargs):
        self.kwargs = kwargs

    def run(self):
        pass


class MessageOne (Message):
    """one message class"""
    def run(self):
         # perform this emssage's action using the kwargs
发件人将实例化并发送一条消息:

queue.put(MessageOne(one='Eins', two='Deux'))
接收方只需获取一个消息对象并执行它的run方法(无需通过可用的消息类型执行它..else..):


另一个有趣的选择是传入一个lambda

q.put(lambda: HandleMsg(1,2))
q.put(lambda: HandleAnother(8, "hello", extra="foo"))

def DestinationThread() :
   while True :
      f = q.get()
      f()

你能发布你得到的错误吗?它不能回答问题。队列中的每个项目都需要编码一个函数和未知数量的参数。将每个参数作为单独的值推送到队列中没有帮助。实际上,第二个代码片段是相关的-上面的代码片段更有用。谢谢!我不支持或reject Geo的回答,我只是相信提问的人想知道为什么有人认为它可能不符合要求。感谢你的回答……毕竟,即使在我们回答问题时,我们也希望得到反馈。干杯,J。这也可行,但需要谨慎,以避免意外结果。请参阅
msg = queue.get()
msg.run()
q.put(lambda: HandleMsg(1,2))
q.put(lambda: HandleAnother(8, "hello", extra="foo"))

def DestinationThread() :
   while True :
      f = q.get()
      f()