2

我想听听你对设计的建议。我有一个控制温度的烤箱,我正在做一些与温度相关的测量。我基本上是在设置温度,测量一些东西然后继续前进。

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

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)

我倾向于第二种设计,但我对你的建议很感兴趣。如果有更好的方法,请不要犹豫告诉我。

4

2 回答 2

1

@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

希望这可以帮助。

于 2013-11-07T19:56:57.697 回答
0

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

于 2013-11-07T19:56:29.393 回答