[英]Python 3.9: async_generator can't be used in 'await' expression
I'm trying the following:我正在尝试以下操作:
class Payload_Session_Generator:
def __init__(self):
pass
async def __anext__(self):
async for payload in generate_fb_payload():
if type(payload) != str:
yield payload
else:
StopAsyncIteration
def __aiter__(self):
return self
This is then passed as an instance to a different function and the __aiter__
method is called explicitly and _iter
is an object of the above class:然后将其作为实例传递给另一个 function 并显式调用
__aiter__
方法, _iter
是上述 class 的 object:
chunk = await self._iter.__anext__()
This then yields the following error:然后会产生以下错误:
TypeError: object async_generator can't be used in 'await' expression
TypeError: object async_generator 不能用于 'await' 表达式
Change your code like更改您的代码,例如
class PayloadSessionGenerator:
def __init__(self):
pass
async def __aiter__(self):
async for payload in generate_fb_payload():
if type(payload) != str:
yield payload
else:
StopAsyncIteration
try next call尝试下一个电话
x = Payload_Session_Generator()
chunk = await x.__anext__()
An asynchronous generator is similar to a regular generator: __anext__
must provide one element each time it is called.异步生成器与常规生成器类似:
__anext__
每次调用时都必须提供一个元素。 Since an (async) generator is an (async) iterator, it must return the object itself.由于(异步)生成器是(异步)迭代器,因此它必须返回 object 本身。
As such, __anext__
should use return
instead of yield
:因此,
__anext__
应该使用return
而不是yield
:
class Payload_Session_Generator:
async def __anext__(self):
async for payload in generate_fb_payload():
if type(payload) != str:
return payload # return one element
else:
raise StopAsyncIteration # raise at end of iteration
def __aiter__(self):
return self
Note that if a class uses just __anext__
and __aiter__
, it is simpler to write a proper async generator.请注意,如果 class 仅使用
__anext__
和__aiter__
,则编写适当的异步生成器会更简单。 An async generator is defined using async def
and yield
in the body:异步生成器在主体中使用
async def
和yield
定义:
async def payload_session_generator(self):
async for payload in generate_fb_payload():
if type(payload) != str:
yield payload # yield each element
else:
break # exiting ends iteration
I had a different scenario:我有一个不同的场景:
async def get_body_file(
request: Request,
) -> AsyncGenerator[str, None]:
loop = asyncio.get_event_loop()
bytes_written = 0
try:
with tempfile.NamedTemporaryFile(delete=False) as fp:
async for chunk in request.stream():
bytes_written += len(chunk)
if bytes_written > MAX_FILE_SIZE:
raise HTTP_BAD_REQUEST(
"file-limit-exceeded",
f"The maximum file limit has been exceeded, maximum allowed: {MAX_FILE_SIZE} bytes.",
)
await loop.run_in_executor(None, fp.write, chunk)
if bytes_written == 0:
raise HTTP_BAD_REQUEST("body-expected", "No data received")
yield fp.name
finally:
try:
await loop.run_in_executor(None, os.unlink, fp.name)
except FileNotFoundError:
pass
for me it was to await this way:对我来说,就是这样等待:
...///
file = await get_body_file(request).__anext__()
...///
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.