一尘不染

Python观察者模式:示例,提示?

python

是否有用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()功能的简短,完整和“合并的消息”输出。

但是,我想支持多个结果/输出流(到终端的进度条,对日志文件的调试和警告,从成功作业到一个文件/目录的输出,错误消息以及从不成功作业到其他结果的其他结果)等)。

这听起来像是一种情况,要求Observer …让我的类的实例接受其他对象的注册,并在事件发生时使用特定类型的事件进行回调。

我正在查看PyPubSub,因为我在SO相关问题中看到了对此的一些引用。我不确定是否已准备好将外部依赖项添加到我的实用程序中,但是如果这样做可以使其他人更容易使用,则可以看到将其接口用作我的模型的价值。(该项目既可以用作独立的命令行实用程序,也可以用作编写其他脚本/实用程序的类)。

简而言之,我知道该怎么做…但是有很多方法可以实现它。从长远来看,我想就最可能对其他代码用户起作用的建议。

代码本身位于:classh


阅读 159

收藏
2020-12-20

共1个答案

一尘不染

但是,它确实缺乏灵活性。

好吧……实际上,如果您想要异步API,那么对我来说这似乎是一个不错的设计。通常是这样。也许您所需要的只是从stderr切换到Python的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)或类似电话。

2020-12-20