[英]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“收益与回调”问题。 如果您想阅读, 这里是一个链接,但我总结一下:
有三种常见的模式可用来解决“报告反馈”的要求:
yield
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_temperature
用t
做不同的事情(例如,您调用它,并且在某些结果中,您使用一件事,而在另一些结果中使用另一件事),则需要生成器版本。 如果每次调用step_temperature
,都希望对每个项目执行相同的操作,并且两者之间没有不同的计算,那么我将使用回调版本。 这样,使用您的代码的任何人都不必知道何时为t
调用其处理函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.