更多pythonic方式来管理回调列表

时间:2013-09-12 21:41:10

标签: python callback

我正在编写一个带有串行IO的多线程Python应用程序,我在IO类中有这个构造:

def __init__(self):
    # Register these with thread-safe functions having the arguments listed
    self.callbacks_status = [] # args: (pod_index, message, color)
    self.callbacks_conn   = [] # args: (pod_index, message, color)
    self.callbacks_angle  = [] # args: (pod_index, angle_deg)
    self.callbacks_brake  = [] # args: (brake_on)

然后,当我的一个更新线程获得新状态时,我每次都会这样做:

        for func in self.callbacks_conn:
            func(i, "Open", "yellow")

毋庸置疑,这是丑陋的,感觉不是pythonic。是否有更优雅的方法来调用具有相同参数的函数列表?基本上我正在反向寻找map函数。

1 个答案:

答案 0 :(得分:3)

您可以使用附加方法'fire'将其封装在一个特殊列表中,这样您就可以使用一些args“触发”回调列表:

class CallbackList(list):
     def fire(self, *args, **kwargs):
         for listener in self:
             listener(*args, **kwargs)

然后,你管理这样的事情:

def __init__(self):
    self.callbacks_status = CallbackList()
    self.callbacks_conn = CallbackList()
    self.callbacks_angle = CallbackList()
    self.callbacks_brake = CallbackList()

触发回调,你会这样做:

self.callbacks_conn.fire(i, "Open", "yellow")

使用示例:

>>> def print_double(x):
...     print "%s doubled is %s" % (x, x * 2)
>>> def print_square(x):
...     print "%s squared is %s" % (x, x * x)
>>> cb = CallbackList()
>>> cb.append(print_double)
>>> cb.append(print_square)
>>> cb.fire(8)
8 doubled is 16
8 squared is 64