回调与基于生成器的设计

2024-04-25 01:41:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我想听听你对设计的意见。我有一个控制温度的烤箱,我在做一些温度相关的测量。我基本上是设定温度,测量一些东西然后继续。在

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

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)

第二个设计是基于生成器的设计

^{pr2}$

我倾向于第二种设计,但我对你的建议很感兴趣。如果有更好的方法,尽管告诉我。在


Tags: 方法selfforratestepcallback温度start
2条回答

@P3trus。我最近在StackExchange的CodeReview上回答了一个非常类似的Python“yield vs callback”问题。如果你想读它,here's a link但是我总结一下:

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

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

yield和回调都允许您将UI/IO的表示细节与模型或计算代码分开。这很好。两者都很好。在

如果您使用Python的yield,请确保您很好地理解iterables和generator,因为有几种语言实现了yield关键字,但是在实现方面有细微的差异,例如,如果您习惯了C的yield,您可能会感到惊讶。这里的a reference很微妙,但值得一读。实际上,在Python中,当您的函数产生时,它返回一个生成器,该生成器可以有效地分配给变量,捕捉到该点的迭代,但您可能希望也可能不希望这样做。别让它吓到你;yield很好。在

回调确实有一个很好的优势,因为它们允许与调用者(在模型或计算代码中)通信back,可以用来暂停或停止处理,或者以其他方式向模型发送消息。这是一个很好的职责分离,如果你使用yield,它可以让交流变得更加困难。或许不是。总有办法的。:)

例如,在更新报告的温度时,回调还可以监视按钮或键,并向调用者返回一个值,该值可以指示(例如)用户希望中止处理,并且这不会在知道特定UI或IO的情况下污染模型。在

因此,与其只是:

callback(t)

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

^{pr2}$

希望这有帮助。在

如果您偶尔在每次调用step_temperature时使用t执行不同的操作(比如,您调用它,并且一些结果,您只使用一种方法,而另一些方法使用另一种方法),那么您将需要生成器版本。如果每次调用step_temperature,您希望对每个项执行相同的操作,并且在计算之间没有差异,那么我将使用回调版本。这样,使用您的代码的任何人都不必知道何时调用t的处理函数。在

相关问题 更多 >