如何混合
async with api.open() as o: ...
和
o = await api.open()
在一个功能?
由于第一需要的对象与__aenter__
和__aexit__
,但第二要求__await__
,这应该是没有发电机await
.
我的尝试是:
def AsyncContext(aenter, aexit): class AsyncContextClass: async def __aenter__(self): return await aenter() async def __aexit__(self, *args): return await aexit(*args) def __await__(self): return (yield from aenter()) return AsyncContextClass()
但是__await__
如果aenter
使用async def
(TypeError: cannot 'yield from' a coroutine object in a non-coroutine generator
)定义则失败.
它与@asyncio.coroutine
装饰器工作正常aenter
,但这是"脏".
你可以返回__aenter__
的__await__
从你的类__await__
:
# vim: tabstop=4 expandtab import asyncio class Test(object): async def __aenter__(self): print("enter") async def __aexit__(self, *args): print("exit") def __await__(self): return self.__aenter__().__await__() async def run(): async with Test(): print("hello") await Test() loop = asyncio.get_event_loop() loop.run_until_complete(run()) loop.close()
输出:
enter hello exit enter