龙卷风的"产量"和机制中的asyncio的"产量"之间的差异?

Sta*_*ant 23 python yield generator tornado

在Tornado中,我们通常编写以下代码来异步调用函数:

class MainHandler(tornado.web.RequestHandler):

    @tornado.gen.coroutine
    def post(self):
        ...
        yield self.handleRequest(foo)
        ...

    @tornado.gen.coroutine
    def handleRequest(self, foo):
        ...
Run Code Online (Sandbox Code Playgroud)

但是在asyncio中(将随Python 3.4一起提供,可以从pip for Python 3.3安装),我们yield from用来实现同样的目的:

@asyncio.coroutine
def myPostHandler():
    ...
    yield from handleRequest(foo)
    ...


@asyncio.coroutine
def handleRequest(foo)
    ...
Run Code Online (Sandbox Code Playgroud)

从代码看,差异是yieldyield from.然而,前者handleRequest(foo)返回一个tornado.concurrent.Future对象,后者返回一个generator对象.

我的问题是,机制中两件事之间有什么区别?控制流程如何?谁调用实际handleRequest并检索其返回值?

附加:我具有Python生成器和迭代器的基本知识.我想通过使用这些来了解Tornado和asyncio的成就,以及这两种机制之间的区别.

Mar*_*ers 22

两者之间存在巨大差异.yield from采取另一个发电机,并继续从该发电机屈服(委托责任,因为它).yield只产生一个值.

换句话说,yield from在最简单的情况下,可以替换为:

for value in self.handleRequest(foo):
    yield value
Run Code Online (Sandbox Code Playgroud)

如果您更换了yield from <expression>一行,yield <expression>则将整个生成器返回给调用者,而不是生成器生成的值.

yield from语法只在Python 3.3推出,请参阅PEP 380:语法委托给一个子发生器.除了Python 3.3之外,Tornado还支持Python版本2.6,2.7和3.2,因此它不能依赖于yield from可用的语法.asyncio另一方面,作为3.4中添加的核心Python库,可以完全依赖于yield from可用的生成器委派语法.

因此,龙卷风将不得不对从@tornado.gen.coroutine发电机产生的值进行后处理,以检测tornado.concurrent.Future物体的产生; 该@asyncio.coroutine代码处理可以更简单.事实上,Tornado Runner.run()方法会执行显式类型检查来处理委派任务.

  • 除了使转子更简单之外,`yield from`也更快,并且在出现错误时往往会产生更好的堆栈跟踪.另一方面,Tornado使用`yield`在协同程序和非协同程序之间提供了更好的互操作性(包括具有显式回调的异步逻辑和线程执行程序). (4认同)
  • @StarBrilliant:但你的问题似乎是关于语法差异; `yield from`使得转轮代码更简单; `tornado`必须使用显式包装来处理委托,`asyncio`可以依赖语法来代替委托. (2认同)