I'm learning Python await / async syntax and wondering how coroutine can be implemented without async, await or yield. For example, I made this simple three seconds timer with async def syntax:
import asyncio
async def coroutine():
count = 0
while count < 3:
count += 1
print(count)
await asyncio.sleep(1)
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine())
loop.close()
The result:
1
2
3
I noticed that we can implement a Coroutine object by implementing __await__
(https://docs.python.org/3.6/reference/datamodel.html#awaitable-objects). So I can successfully remove await
.
import asyncio
class Generator():
def __await__(self):
count = 0
while count < 3:
count += 1
print(count)
yield from asyncio.sleep(1)
loop = asyncio.get_event_loop()
loop.run_until_complete(Generator())
loop.close()
Finally, I want to implement the iterator without yield like that:
import asyncio
class Iterator():
def __init__(self):
self.count = 0
def __iter__(self): return self
def __await__(self): return self
def __next__(self):
if self.count < 3:
self.count += 1
print(self.count)
return next(asyncio.sleep(1))
else:
raise StopIteration()
loop = asyncio.get_event_loop()
result = loop.run_until_complete(Iterator())
loop.close()
But it didn't work. It stops after it shows '1'.
I know this doesn't have any practical value, but I want to know it to understand asyncio correctly. Can I implement a Coroutine without await or yield? If so how to do it? I tested it by Python 3.6.7.