为什么这个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 表达式的值取决于恢复执行的方法。
所有这些都使得生成器函数与协程非常相似;它们产生多次,它们有多个入口点,并且它们的执行可以暂停。唯一的区别是生成器函数无法控制在生成后应继续执行的位置;控制权始终转移到生成器的调用方。