__aenter__
and __aexit__
必须返回等待对象,但是看看当您调用示例中的等待对象时会发生什么:
>>> class AsyncContextManager:
... async def __aenter__(self):
... await log('entering context')
... async def __aexit__(self, exc_type, exc, tb):
... await log('exiting context')
...
>>> AsyncContextManager().__aenter__()
<coroutine object AsyncContextManager.__aenter__ at 0x7f5b092d5ac0>
它没有回来None
!我们得到了一个协程对象,它是可等待的。
这些方法是async
函数,它自动返回(可等待的)异步协程。return
正文中的语句async
函数确定当您返回什么时await
协程,而不是调用函数时返回的内容。
这类似于生成器函数返回生成器迭代器的方式,尽管它们通常没有return
声明,以及如果你写的话怎么写__iter__
作为生成器函数,您不应该尝试return
生成器函数内的迭代器。
那么如果你确实放了一个会发生什么return
in __aenter__
or __aexit__
定义为async
功能?好吧,你可以,如果你这样做了,return
语句不必返回可等待的。这就是 Python 将要做的事情。
If you return
某事从__aenter__
定义为async
函数,它决定绑定到什么as
目标,如果async with
uses as
.
If you return
某事从__aexit__
定义为async
函数,它确定是否抑制块内引发的异常。 “真实”值告诉async with
抑制异常,而“假”值告诉async with
让异常传播。默认None
为 false,因此默认情况下不会抑制异常。
这是一个例子:
import asyncio
class Example:
async def __aenter__(self):
return 3
async def __aexit__(self, exc_type, exc, tb):
return True
async def example():
async with Example() as three:
print(three == 3)
raise Exception
print("Exception got suppressed")
asyncio.run(example())
Output:
True
Exception got suppressed