[英]Python 3.9: async_generator can't be used in 'await' expression
我正在嘗試以下操作:
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
然后將其作為實例傳遞給另一個 function 並顯式調用__aiter__
方法, _iter
是上述 class 的 object:
chunk = await self._iter.__anext__()
然后會產生以下錯誤:
TypeError: object async_generator 不能用於 'await' 表達式
更改您的代碼,例如
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
嘗試下一個電話
x = Payload_Session_Generator()
chunk = await x.__anext__()
異步生成器與常規生成器類似: __anext__
每次調用時都必須提供一個元素。 由於(異步)生成器是(異步)迭代器,因此它必須返回 object 本身。
因此, __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
請注意,如果 class 僅使用__anext__
和__aiter__
,則編寫適當的異步生成器會更簡單。 異步生成器在主體中使用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
我有一個不同的場景:
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
對我來說,就是這樣等待:
...///
file = await get_body_file(request).__anext__()
...///
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.