Python 不能';来自'的收益率;非协程生成器中的协程对象
我尝试运行协同程序。我编写了一个正确的演示:Python 不能';来自'的收益率;非协程生成器中的协程对象,python,generator,python-asyncio,coroutine,event-loop,Python,Generator,Python Asyncio,Coroutine,Event Loop,我尝试运行协同程序。我编写了一个正确的演示: import asyncio async def outer(): print('in outer') print('waiting for result1') result1 = await phase1() print('waiting for result2') result2 = await phase2(result1) return (result1, result2) async de
import asyncio
async def outer():
print('in outer')
print('waiting for result1')
result1 = await phase1()
print('waiting for result2')
result2 = await phase2(result1)
return (result1, result2)
async def phase1():
print('in phase1')
return 'result1'
async def phase2(arg):
print('in phase2')
return 'result2 derived from {}'.format(arg)
event_loop = asyncio.get_event_loop()
try:
return_value = event_loop.run_until_complete(outer())
print('return value: {!r}'.format(return_value))
finally:
event_loop.close()
我想知道如果外部函数不是一个协程,我会删除async
,然后:
import asyncio
def outer():
print('in outer')
print('waiting for result1')
result1 = yield from phase1()
print('waiting for result2')
result2 = yield from phase2(result1)
return (result1, result2)
async def phase1():
print('in phase1')
return 'result1'
async def phase2(arg):
print('in phase2')
return 'result2 derived from {}'.format(arg)
event_loop = asyncio.get_event_loop()
try:
return_value = event_loop.run_until_complete(outer())
print('return value: {!r}'.format(return_value))
finally:
event_loop.close()
然后我运行这个事件循环,我发现了这个错误。如何解释这个错误?不允许使用一个普通的函数来调用协程?我曾经认为,可以在常规函数中使用yield from,但在这里,它绝对不能。谁能告诉我原因呢?Python3.5+要求使用
async def
或@asyncio.coroutine
为许多操作定义协程(例如wait x
)如果您试图传递任何不符合此条件的内容,将抛出异常
请参见python 3.5文档和:
很明显,这个错误告诉我只在协同程序中使用yield from。但是我想知道为什么,因为它可以在普通的生成器中使用。使用
async def
创建的协同程序对象根本不是生成器,所以不能从它中产生。您可以从中提取一个生成器并从中生成,例如,从phase1()生成。\uuuu wait\uuuuuu()
,但我看不出您想要这样做的原因。一般来说,每当您询问错误时,请包括错误的完整回溯。大多数错误都可以通过仔细阅读回溯来理解。@SvenMarnach抱歉,谢谢你友好的建议,我刚刚注册了stackorverflow,这是我的第一个问题,我只是不知道stackoverflow的规则,我会记住的。3Q@michael:您仍然可以编辑问题并添加回溯。不客气。如果这是正确答案,请点击复选标记图标以接受它:-)请参阅:。祝你在堆栈溢出中好运!
def isawaitable(object):
"""Return true if object can be passed to an ``await`` expression."""
return (isinstance(object, types.CoroutineType) or
isinstance(object, types.GeneratorType) and
bool(object.gi_code.co_flags & CO_ITERABLE_COROUTINE) or
isinstance(object, collections.abc.Awaitable))