【问题标题】:Why does this python autobahn code need to use the 'yield' keyword?为什么这个 python 高速公路代码需要使用 'yield' 关键字?
【发布时间】:2015-02-06 07:03:14
【问题描述】:

为什么这个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 python-2.7 twisted autobahn


    【解决方案1】:

    因为 Python 的标准库 sleep 会阻塞 Twisted 反应器,而 Autobahn 的 Twisted 助手 sleep 将返回一个 Twisted Deferred(而不是阻塞反应器):https://github.com/tavendo/AutobahnPython/blob/master/autobahn/autobahn/twisted/util.py#L29

    【讨论】:

    • 谢谢。我想你得到了正确的答案。改变了我选择的答案。但这很可怕。我怎么知道我的其他 python 代码最终不会阻止 Twister?
    • 您必须知道 Python 标准库的哪些部分在后台阻止系统调用。本质上,stdlib 中与网络相关的所有内容都是阻塞的。
    【解决方案2】:

    使用yield sleep(1)可以返回一个结果并做其他事情。

    但是简单地使用sleep(1) 将导致main 总是在函数onJoin 中。 这是一个死循环。

    点击here

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

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

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

    【讨论】:

    • 谢谢。但为什么不return sleep(1)
    • return sleep(1) 终止 while 循环。
    猜你喜欢
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    • 2020-05-20
    • 2021-09-06
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    相关资源
    最近更新 更多