Home > Software engineering >  Python's SendType and ReturnType in Generators
Python's SendType and ReturnType in Generators

Time:05-03

So I was tinkering with generators, and i found out that generators have a typing object (i.e. generators have an alias) I then stumbled upon documentation for the typing.Generator object on https://docs.python.org/3/library/typing.html#typing.Generator and this is what the docs have to say:

A generator can be annotated by the generic type Generator[YieldType, SendType, ReturnType].

Which got me wondering on how to modify the SendType and ReturnType thingys The docs suggested this as an example:

def echo_round() -> Generator[int, float, str]:
    sent = yield 0
    while sent >= 0:
        sent = yield round(sent)
    return 'Done'

I assume that the second sent declaration is what defines the SendType, but yield 0 returns None (or doesnt return anything in the first place), and therefore raises TypeError: '>=' not supported between instances of 'NoneType' and 'int'

How does SendType work, how do I modify it, and what are cases in which SendType and ReturnType are useful?

CodePudding user response:

Generators have a send method:

generator.send(value)

Resumes the execution and “sends” a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value.

See also What's the purpose of "send" function on Python generators?

So with your generator you can do this:

it = echo_round()
print(next(it))      # 0 -- we could also have printed: it.send(None) 
print(it.send(1.1))  # 1
print(it.send(2.5))  # 2
print(it.send(-1.8)) # StopIteration: Done

...but yield 0 returns None

...unless we call send after the first yield has been made, like in the above script. Here yield 0 will return 1.1

We see all three types at play here:

it.send(1.1) takes a value of the SendType (float in this case), and returns a value of the YieldType (int in this case), or raises a StopIteration error with a value of the ReturnType (str in this case).

  • Related