I am trying to learn how generators work and part of that is the `send()` command that allows me to change the operation of the generator by sending back information to the generator.
I have a very simple example in which I am sending back the yielded value and add it to an internal `status`.
The generator can be started specifying the number of values it is supposed to yield.
The incredibly strange thing is: When I start the generator with an even number it works, however if I ask to yield an odd number of values I get an `StopIteration` error.
To debug, I added a simple `print()` to keep track of how many iterations it goes through and it seems like it does two iterations per `yield` statement, which makes no sense to me.
generator that jumps ahead
status = 1
iteration = 0
while iteration < length:
iteration += 1
print("iteration: ", iteration)
result = (yield status)
if result is not None:
status += result
if __name__ == "__main__":
# simple generator that expects a value back
# this works
jumpy = jump_ahead(4)
for i in jumpy:
# this does not
jumpy_fail = jump_ahead(5)
for i in jumpy_fail:
The output looks something like this
As it is said in the docs,
> `generator.send()` 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.
Your code is not doing "two iterations per yield". It is iterating twice because you are yielding twice:
- In the `for...in...` statement
- By calling `.send()`
And `StopIteration` is actually raised on both. With `jump_ahead(4)` it is caught and handled by the `for ... in ...` statement. That's how `for ... in` statements know when to [stop iterating](https://docs.python.org/3/library/exceptions.html#StopIteration).
However, with odd numbers as you have observed, StopIteration was raised when calling `.send()`.