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 raisesStopIteration
if the generator exits without yielding another value. Whensend()
is called to start the generator, it must be called withNone
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).