簡體   English   中英

Python 3.9: async_generator 不能用於 'await' 表達式

[英]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 defyield定義:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM