为什么这个python高速公路代码需要使用'yield'关键字?



为什么这个python高速公路示例代码使用yield sleep(1)而不是简单的sleep(1)

class Component(ApplicationSession):
       """
   An application component that publishes an event every second.
   """
   @inlineCallbacks
   def onJoin(self, details):
      print("session attached")
      counter = 0
      while True:
         print(".")
         self.publish('com.myapp.topic1', counter)
         counter += 1
         yield sleep(1)
if __name__ == '__main__':
   from autobahn.twisted.wamp import ApplicationRunner
   runner = ApplicationRunner("ws://127.0.0.1:8080/ws", "realm1")
   runner.run(Component)

因为 Python 的标准库sleep会阻止扭曲的反应堆,而 Autobahn 的扭曲sleep助手会返回一个扭曲的延迟(而不是阻塞反应堆(: https://github.com/tavendo/AutobahnPython/blob/master/autobahn/autobahn/twisted/util.py#L29

使用 yield sleep(1) 可以返回结果并执行其他操作。

但是使用简单的sleep(1)会导致main总是在功能onJoin。这是一个无死的循环。

点击这里

yield 表达式仅在定义生成器函数时使用,并且只能在函数定义的主体中使用。在函数定义中使用 yield 表达式足以使该定义创建生成器函数而不是普通函数。

调用生成器函数时,它会返回一个称为生成器的迭代器。然后,该生成器控制生成器函数的执行。当调用生成器的方法之一时,执行开始。此时,执行继续执行到第一个 yield 表达式,在那里它再次挂起,将 expression_list 的值返回给生成器的调用方。暂停是指保留所有局部状态,包括局部变量的当前绑定、指令指针和内部评估堆栈。当通过调用生成器的方法之一恢复执行时,该函数可以完全像 yield 表达式只是另一个外部调用一样继续执行。恢复后 yield 表达式的值取决于恢复执行的方法。

所有这些都使得生成器函数与协程非常相似;它们产生多次,它们有多个入口点,并且它们的执行可以暂停。唯一的区别是生成器函数无法控制在生成后应继续执行的位置;控制权始终转移到生成器的调用方。

最新更新