繁体   English   中英

回调与基于生成器的设计

[英]callback vs generator based design

我想获得您的设计建议。 我有一个烤箱控制温度,并且正在执行一些温度相关的测量。 我基本上是在设定温度,测量一些东西然后继续前进。

我想出了两种设计,它们当然经过了简化,如下所示。 第一个使用基于回调的方法:

class Oven(object):
    # ... some methods
    def step_temperature(start, stop, num, rate, callback):
        temperatures = np.linspace(start, stop, num)
        for t in temperatures:
            self.temperature = t, rate # sweep to temperature with given rate
            self._wait_for_stability() # wait until temperature is reached.
            callback(t)                # execute the measurement
# Use Case
oven = Oven()
oven.step_temperature(start=20, stop=200, num=10, rate=1, callback=measure_stuff)

第二种设计是基于发电机的设计

class Oven(object):
    # ... some methods

    def step_temperature(start, stop, num, rate):
        temperatures = np.linspace(start, stop, num)
        for t in temperatures:
            self.temperature = t, rate
            self._wait_for_stability()
            yield t
# Use Case
oven = Oven()
for t in oven.step_temperature(start=20, stop=200, num=10, rate=1):
    measure_stuff(t)

我正在尝试第二个设计,但是我对您的建议很感兴趣。 如果有更好的方法,请随时告诉我。

@ P3trus。 我最近在StackExchange的CodeReview上回答了一个非常类似的Python“收益与回调”问题。 如果您想阅读, 这里是一个链接,但我总结一下:

有三种常见的模式可用来解决“报告反馈”的要求:

  1. yield
  2. 回调函数
  3. 内联,硬编码的反馈

yield和回调都允许您将UI / IO的表示详细信息与模型或计算代码分开。 很好 两者都运作良好。

如果您使用Python的yield ,请确保您很好地理解了可迭代对象和生成器,因为多种语言实现了yield关键字,但实现方面的细微差别可能会使您感到惊讶,例如,如果您习惯于C#的yield 这是一个参考 ,虽然有些微妙但值得一读。 本质上,在Python中,当函数产生时,它会返回一个生成器,该生成器可以有效地分配给变量,从而捕获到该点的迭代,但是您可能想要也可能不想这样做。 不要让那吓到你; yield好。

回调确实有一个很好的优点,因为它们允许通信返回给调用者(在模型或计算程序),它可以用来暂停或停止处理或以其他方式将消息发送到模型。 这是很好的职责分离,如果您使用yield 则允许进行交流可能会更加困难。 或者可能不是。 总会有办法的。 :)

例如,在更新报告的温度时,回调还可以监视按钮或按键,并向调用方返回一个值,该值可以指示例如用户想要中止处理,并且这不会污染具有特定UI的模型。或IO。

因此,不仅仅是:

callback(t)

您可以让callback执行其温度报告工作,还可以侦听它可能从用户那里收集的内容,例如:

if callback(t) == ABORT_BUTTON_PRESSED:
    self.shutdown  # or whatever

希望这可以帮助。

如果您偶尔会在每次调用step_temperaturet做不同的事情(例如,您调用它,并且在某些结果中,您使用一件事,而在另一些结果中使用另一件事),则需要生成器版本。 如果每次调用step_temperature ,都希望对每个项目执行相同的操作,并且两者之间没有不同的计算,那么我将使用回调版本。 这样,使用您的代码的任何人都不必知道何时为t调用其处理函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM