2 回答

TA贡献1752条经验 获得超4个赞
该语言并不关心您返回哪个迭代器。该错误来自asyncio库,该库对迭代器必须生成的值类型有特定的想法。Asyncio 需要__await__
生成 asyncio future(包括其子类型,例如任务)或None
. 其他库,如 curio 和 trio,将期望不同类型的值。总的来说,异步库不会记录他们的期望,__await__
因为他们认为这是一个实现细节。
就 asyncio 而言,除了协程之外,您还应该使用更高级别的构造,例如 future 和任务,并等待它们。很少需要__await__
手动实现,即使这样,您也应该使用它来委托另一个可等待的信号。编写一个__await__
创建并产生自己的新挂起值的方法需要将其与事件循环结合起来并了解其内部结构。
您可以将其视为__await__
编写类似于 asyncio 的库的工具。如果您是此类库的作者,则当前规范就足够了,因为您可以从迭代器中生成任何您喜欢的内容,只有事件循环中的代码才会观察生成的值。如果您不处于这个位置,您可能不需要实施__await__
.

TA贡献1795条经验 获得超7个赞
任务只能等待其他任务/未来。来自CPython 源代码:
/* Check if `result` is FutureObj or TaskObj (and not a subclass) */
/* ... */
/* Check if `result` is None */
/* ... error */
/* Check if `result` is a Future-compatible object */
/* ... */
/* Check if `result` is a generator */
/* ... */
/* The `result` is none of the above */
o = task_set_error_soon(
task, PyExc_RuntimeError, "Task got bad yield: %R", result);
Py_DECREF(result);
return o;
编辑:如果我理解正确的话,此限制仅施加于任务,并且正常的 future 可以等待从 返回的任何可迭代对象__await__
,尽管重点可能是返回的可迭代对象产生事件循环,然后最终返回结果。
添加回答
举报