Search code examples
pythonooppython-asyncio

How to subclass coroutine?


I want my class MyCoro to behave as same as coroutine. I am looking for something like this as class definition:

class MyCoro(Coroutine?):
    def __init__(self, text):
        async def coro():
            await asyncio.sleep(5)
            print(text)

        super().__init__(coro())

So that I can use it like this:

asyncio.create_task(MyCoro("Hello!"))

# Above is same as:

async def coro(text):
    await asyncio.sleep(5)
    print(text)

asyncio.create_task(coro("Hello!"))

How can I do this?


Solution

  • You can create a class with an async __call__ method, like:

    import asyncio
    
    class Coroutine:
        def __init__(self, text):
            self.text = text
    
        async def __call__(self):
            for i, word in enumerate(self.text.split()):
                print(' '*i, word)
                await asyncio.sleep(0.5)
    
    async def main():
        coro = Coroutine("it's time to light the lights")
        await coro()
    
    asyncio.run(main())
    

    Noting, of course, that you don't actually need to call create_task; you could rewrite main like this:

    async def main():
        coro = MyCoroutine("it's time to light the lights")
        await coro()