支持多通道订户的Python可观察实现
在twisted应用程序中,我有一系列资源控制器/管理器类,它们通过可观察模式进行交互。一般来说,大多数观察家都会订阅特定频道(例如“foo.bar.entity2”),但也有一些情况下,我想了解特定频道(例如“foo.*)中的所有事件,所以我写了如下内容:支持多通道订户的Python可观察实现,python,Python,在twisted应用程序中,我有一系列资源控制器/管理器类,它们通过可观察模式进行交互。一般来说,大多数观察家都会订阅特定频道(例如“foo.bar.entity2”),但也有一些情况下,我想了解特定频道(例如“foo.*)中的所有事件,所以我写了如下内容: from collections import defaultdict class SimplePubSub(object): def __init__(self): self.s
from collections import defaultdict
class SimplePubSub(object):
def __init__(self):
self.subjects = defaultdict(list)
def subscribe(self, subject, callbackstr):
"""
for brevity, callbackstr would be a valid Python function or bound method but here is just a string
"""
self.subjects[subject].append(callbackstr)
def fire(self, subject):
"""
Again for brevity, fire would have *args, **kwargs or some other additional message arguments but not here
"""
if subject in self.subjects:
print "Firing callback %s" % subject
for callback in self.subjects[subject]:
print "callback %s" % callback
pubSub = SimplePubSub()
pubSub.subscribe('foo.bar', "foo.bar1")
pubSub.subscribe('foo.foo', "foo.foo1")
pubSub.subscribe('foo.ich.tier1', "foo.ich.tier3_1")
pubSub.subscribe('foo.ich.tier2', "foo.ich.tier2_1")
pubSub.subscribe('foo.ich.tier3', "foo.ich.tier2_1")
#Find everything that starts with foo
#say foo.bar is fired
firedSubject = "foo.bar"
pubSub.fire(firedSubject)
#outputs
#>>Firing callback foo.bar
#>>callback foo.bar1
#but let's say I want to add a callback for everything undr foo.ich
class GlobalPubSub(SimplePubSub):
def __init__(self):
self.globals = defaultdict(list)
super(GlobalPubSub, self).__init__()
def subscribe(self, subject, callback):
if subject.find("*") > -1:
#assumes global suscriptions would be like subject.foo.* and we want to catch all subject.foo's
self.globals[subject[:-2]].append(callback)
else:
super(GlobalPubSub, self).subscribe(subject, callback)
def fire(self, subject):
super(GlobalPubSub, self).fire(subject)
if self.globals:
for key in self.globals.iterkeys():
if subject.startswith(key):
for callback in self.globals[key]:
print "global callback says", callback
print "Now with global subscriptions"
print
pubSub = GlobalPubSub()
pubSub.subscribe('foo.bar', "foo.bar1")
pubSub.subscribe('foo.foo', "foo.foo1")
pubSub.subscribe('foo.ich.tier1', "foo.ich.tier3_1")
pubSub.subscribe('foo.ich.tier2', "foo.ich.tier2_1")
pubSub.subscribe('foo.ich.tier3', "foo.ich.tier2_1")
pubSub.subscribe("foo.ich.*", "All the ichs, all the time!")
#Find everything that starts with foo.ich
firedSubject = "foo.ich.tier2"
pubSub.fire(firedSubject)
#outputs
#>>Firing callback foo.bar
#>>callback foo.bar1
#>>Now with global subscriptions
#
#>>Firing callback foo.ich.tier2
#>>callback foo.ich.tier2_1
#>>global callback says All the ichs, all the time!
在不借助某种外来构造的情况下(例如,尝试),这是否达到了预期效果?我在寻找一个关于我走在正确轨道上的肯定,或者一个关于纯python的全局订阅处理程序(没有外部库或服务)的更好的替代建议。这看起来你走在了正确的轨道上。我在wxPython应用程序中使用了一段时间,然后实现了我自己的“更简单”版本,从根本上说,它看起来与您在这里所做的非常相似,只是有一些额外的提示,您可能会在满足需求时实现这些提示 给出的答案也很像你所做的 这涉及到一些不同方法的示例
除此之外,还有许多现有的库,如和,可能值得参考或参考。这看起来你对我来说是正确的。我在wxPython应用程序中使用了一段时间,然后实现了我自己的“更简单”版本,从根本上说,它看起来与您在这里所做的非常相似,只是有一些额外的提示,您可能会在满足需求时实现这些提示 给出的答案也很像你所做的 这涉及到一些不同方法的示例 除此之外,还有许多现有的图书馆,如和,可能值得参考或参考