相关疑难解决方法(0)

__await__ 的精确规范

Python Language Reference 规定object.__await__如下:

object.__await__(self)

必须返回一个迭代器。应该用于实现可等待的对象。例如,asyncio.Future实现此方法以与 await 表达式兼容。

就是这样。我觉得这个规范很模糊,也不是很具体(讽刺的是)。好的,它应该返回一个迭代器,但它可以是一个任意的迭代器吗?显然不是:

import asyncio


class Spam:
    def __await__(self):
        yield from range(10)


async def main():
    await Spam()


asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
RuntimeError: Task got bad yield: 0
Run Code Online (Sandbox Code Playgroud)

我假设asyncio事件循环期望迭代器产生特定类型的对象。那么它究竟应该产生什么?(为什么没有记录在案?)


编辑:据我所知,这在任何地方都没有记录。但我一直在调查我自己,我觉得关键是了解哪些对象asyncio预计其协同程序产生在于task_step_impl_asynciomodule.c


更新:我做了一个PR与此澄清的目的CPython的库:“明确的模糊规范object.__await__。目前正在审核中。

python async-await python-asyncio

9
推荐指数
1
解决办法
612
查看次数

__await__ 需要是生成器吗?

我想实现一个 awaitable 并注意到__await__“需要”是一个生成器。

PEP-492

具有__await__返回迭代器的方法的对象。

...

__await__在本 PEP 的其余部分中,带有方法的对象称为 Future-like 对象。

如果__await__返回除迭代器以外的任何内容,则为 TypeError 。

根据我的经验,beforeawait是一个语句,yield from与作为生成器实现的协程一起使用。如今,python(我使用的是 3.5)具有使用async def语法的异步方法。因此,我认为该yield from语法是旧的/已弃用的。

所以我打破了解释器,看看这是否有效:

>>> class A:
...     def __await__(self):
...         yield from (asyncio.sleep(1).__await__())
...         return 'spam'
... 
>>> a = A()
>>> loop = asyncio.get_event_loop()
>>> loop.run_until_complete(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.5/asyncio/base_events.py", line 467, in run_until_complete
    return future.result() …
Run Code Online (Sandbox Code Playgroud)

python python-asyncio python-3.5

3
推荐指数
1
解决办法
2542
查看次数

标签 统计

python ×2

python-asyncio ×2

async-await ×1

python-3.5 ×1