Python电路加入渠道

时间:2014-07-18 10:34:19

标签: python circuits-framework

我有一个场景,我使用python电路框架动态创建具有自己的频道的新组件。我希望在所有创建的频道都发起特定事件时收到通知。

我已尝试使用成功事件,但这会在每个频道独立触发,因此我每个频道获得一个。因为在不同的数据集上执行相同的任务,所以使用不同的通道是有道理的。

我目前的解决方案是记录创建的频道名称,然后收听整理事件(下面的“频道”)并从列表中删除发射频道。当列表为空时我可以停止。下面是一个例子。它有效,但我觉得一旦完成这些频道,就应该有更优雅的方式加入。

import time
import sys

from circuits import Component, Event
from circuits.core.debugger import Debugger

class boom(Event):
    "boom event"

class Start(Component):
    def __init__(self, channel="*"):
        super(Start, self).__init__(channel=channel)
        self._boom_channels = []
        return

    def started(self, *args):
        for i in [1,2]:
            channel = 'channel_{}'.format(i)
            self._boom_channels.append(channel)

            new = Middle(channel=channel).register(self)

    def boom(self, event, *args):
        new_chans = set(self._boom_channels) - set(event.channels)
        self._boom_channels = list(new_chans)
        print self._boom_channels
        if not self._boom_channels:
            sys.exit()

class Middle(Component):
    def __init__(self, channel="*"):
        super(Middle, self).__init__(channel=channel)
        time.sleep(2)
        self.fire(boom())
        return

if __name__ == '__main__':
    (Start() + Debugger()).run()

1 个答案:

答案 0 :(得分:1)

我相信你在这里有正确的想法。由于这些是混凝土事件,因此无法在不跟踪它们的情况下确定它们何时完整(我不认为)。

我唯一能让你的例子更好的方法是:

#!/usr/bin/env python


from __future__ import print_function


from circuits import Component, Debugger, Event


class boom(Event):
    "boom event"


class Start(Component):

    channel = "start"

    def init(self, channel=channel):
        self.boom_channels = []

    def started(self, *args):
        for i in [1, 2]:
            channel = "channel_{}".format(i)
            self.boom_channels.append(channel)

            Middle(channel=channel).register(self)

    def boom(self, middle):
        self.boom_channels.remove(middle.channel)

        if not self.boom_channels:
            raise SystemExit(0)


class Middle(Component):

    def registered(self, component, manager):
        self.fire(boom(self), manager)
        return


def main():
    app = (Start() + Debugger())
    app.run()


if __name__ == '__main__':
    main()

输出:

$ python test.py 
<registered[*] (<Debugger/* 1156:MainThread (queued=0) [S]>, <Start/start 1156:MainThread (queued=2) [R]> )>
<started[start] (<Start/start 1156:MainThread (queued=1) [R]> )>
<registered[channel_1] (<Middle/channel_1 1156:MainThread (queued=0) [S]>, <Start/start 1156:MainThread (queued=2) [R]> )>
<registered[channel_2] (<Middle/channel_2 1156:MainThread (queued=0) [S]>, <Start/start 1156:MainThread (queued=2) [R]> )>
<boom[<Start/start 1156:MainThread (queued=2) [R]>] (<Middle/channel_1 1156:MainThread (queued=0) [S]> )>
<boom[<Start/start 1156:MainThread (queued=1) [R]>] (<Middle/channel_2 1156:MainThread (queued=0) [S]> )>
<stopped[start] (<Start/start 1156:MainThread (queued=0) [S]> )>

编辑:一些注意事项:

  • 明确将boom()事件推送给经理。
  • 在&#34;之后触发boom()事件&#34;我们已注册。