我有一个场景,我使用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()
答案 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()
事件推送给经理。boom()
事件&#34;我们已注册。