VPfB VPfB -4 years ago 91
Python Question

What is the value of await awaitable_object?

I've been using generator based coroutines before the

asyncio
was released.

Now I'm trying to learn the new
async/await
features introduced in Python 3.5. This is one of my test programs.

class Await3:
def __init__(self, value):
self.value = value
def __await__(self):
return iter([self.value, self.value, self.value])

async def main_coroutine():
x = await Await3('ABC')
print("x =", x)

def dummy_scheduler(cobj):
snd = None
try:
while True:
aw = cobj.send(snd)
#snd = 42
print("got:", aw)
except StopIteration:
print("stop")

dummy_scheduler(main_coroutine())


Its output is:

got: ABC
got: ABC
got: ABC
x = None
stop


The value of
x
is the result of
await awaitable_object
expression. Why is this value
None
and how can I set it to a value I want?

All I could find is that value of
await couroutine()
is determined by the coroutine's return value, but that's not my case.

Uncommenting
snd = 42
does not work. The error is
AttributeError: 'list_iterator' object has no attribute 'send'

Answer Source

If you're going to implement a class with an __await__ method manually, the return value of an await expression on an instance of your class will be whatever argument was used to construct the StopIteration exception at the end of the iterator, or None if there was no argument.

You can't control the StopIteration argument with something like return iter(some_list). You need to write your own iterator. I'd say to write it as a generator and return the value:

class Await3:
    def __init__(self, value):
        self.value = value
    def __await__(self):
        yield self.value
        yield self.value
        yield self.value
        return whatever

which will throw StopIteration(whatever) to end the iteration, but if you wanted to do things the easy way, you would have written an async function in the first place.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download