是否有用Python实现的GoF Observer的示例示例?我有一个位代码,当前有一些调试代码通过键类附加(如果设置了魔术环境,当前会向stderr生成消息)。此外,该类还具有一个接口,用于递增地返回结果以及将其存储在内存中以进行后处理。(该类本身是一个作业管理器,用于通过ssh在远程计算机上并发执行命令)。
当前,该类的用法类似于:
job = SSHJobMan(hostlist, cmd) job.start() while not job.done(): for each in job.poll(): incrementally_process(job.results[each]) time.sleep(0.2) # or other more useful work post_process(job.results)
一种替代用法模型是:
job = SSHJobMan(hostlist, cmd) job.wait() # implicitly performs a start() process(job.results)
这对于当前的实用程序来说一切正常。但是,它确实缺乏灵活性。例如,我目前支持简短的输出格式或进度条作为增量结果,也支持该post_process()功能的简短,完整和“合并的消息”输出。
post_process()
但是,我想支持多个结果/输出流(到终端的进度条,对日志文件的调试和警告,从成功作业到一个文件/目录的输出,错误消息以及从不成功作业到其他结果的其他结果)等)。
这听起来像是一种情况,要求Observer …让我的类的实例接受其他对象的注册,并在事件发生时使用特定类型的事件进行回调。
我正在查看PyPubSub,因为我在SO相关问题中看到了对此的一些引用。我不确定是否已准备好将外部依赖项添加到我的实用程序中,但是如果这样做可以使其他人更容易使用,则可以看到将其接口用作我的模型的价值。(该项目既可以用作独立的命令行实用程序,也可以用作编写其他脚本/实用程序的类)。
简而言之,我知道该怎么做…但是有很多方法可以实现它。从长远来看,我想就最可能对其他代码用户起作用的建议。
代码本身位于:classh。
但是,它确实缺乏灵活性。
好吧……实际上,如果您想要异步API,那么对我来说这似乎是一个不错的设计。通常是这样。也许您所需要的只是从stderr切换到Python的logging模块,该模块具有自己的发布/订阅模型,Logger.addHandler()以及诸如此类的东西。
logging
Logger.addHandler()
如果您确实想支持观察者,我的建议是使其保持简单。您实际上只需要几行代码。
class Event(object): pass class Observable(object): def __init__(self): self.callbacks = [] def subscribe(self, callback): self.callbacks.append(callback) def fire(self, **attrs): e = Event() e.source = self for k, v in attrs.iteritems(): setattr(e, k, v) for fn in self.callbacks: fn(e)
您的Job类可以子类化Observable。发生感兴趣的事情时,请致电self.fire(type="progress", percent=50)或类似电话。
Observable
self.fire(type="progress", percent=50)