在collections.abc.Coroutine子类中使用_aiter_uuuuuuu和_anext_uuu通过手动等待一个Coroutine来添加功能

2024-09-30 02:22:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做一个项目,在一个单独的线程中运行文件I/O,但是我想对我的open()协同程序进行改进。在添加@helper之前,为了使用_Filer类的功能,必须执行以下操作:

async with await open('myfile'): #works fine, just not preferred
  ...
async for i in await open('file.txt'): #also works fine
  ...

AddFunctionality类和helper装饰器的整个要点是为用户await协同路由,因此他们可以像这样使用它:

async with open('file.txt'): #this works
   ...
async for i in open('file.txt'): #this is completely broken
   ...

幸运的是,除了__aiter____anext__(一个async for语句的组件)之外的所有东西都工作得很好。我只是不知道如何在{}和{}的上下文中等待{}。感谢您的帮助

from collections.abc import Coroutine
from functools import wraps


class AddFunctionality(Coroutine):
    __slots__ = ("_coro", "_obj")

    def __init__(self, coro):
        self._coro = coro
        self._obj = None
        print('calling init')
    def send(self, value):
        print('calling send')
        return self._coro.send(value)

    def throw(self, typ, val=None, tb=None):
        print('calling throw')
        if val is None:
            return self._coro.throw(typ)

        if tb is None:
            return self._coro.throw(typ, val)

        return self._coro.throw(typ, val, tb)

    def close(self):
        print('calling close')
        return self._coro.close()

    def __await__(self):
        print('calling await')
        return self._coro.__await__()

    async def __aenter__(self):
        print('calling aenter')
        self._obj = await self._coro
        return self._obj

    async def __aexit__(self, exc_type, exc, tb):
        print('calling aeixt')
        await self._obj.close()
        self._obj = None
    def __aiter__(self):
        return self #
    async def __anext__(self):
        await self._coro # I have no idea what I'm doing 
        #error: RuntimeError: cannot reuse already awaited coroutine

def helper(method):
    @wraps(method)
    def wrapper(*args, **kwargs) -> AddFunctionality:
        return AddFunctionality(method(*args, **kwargs))
    return wrapper

@helper
async def open(*args, **kwargs):
    f =  _Filer(*args, **kwargs)
    #keep in mind that the `_Filer` class has __aiter__, __anext__, __aenter__, and __aexit__ attributes
    await f.returner() #this just opens the file up. it's not relevant to my question
    return f```

Tags: selfhelpernoneobjasyncreturndefopen

热门问题