Reputation: 8380
Here's an infinite looper which I've added row number prints to to facilitate tracing of the program execution.
def infinite_looper(objects):
count = 0
print("row 35")
while True:
print("row 37")
if count >= len(objects):
count = 0
print("Row 40")
message = yield objects[count]
print("row 42")
print("The message is "+str(message))
print("row 44")
if message != None:
count = 0 if message < 0 else message
print("row 47, count = "+str(count))
else:
count += 1
print("row 50")
print("Row 51")
x = infinite_looper("abcdefghijkl")
print("executing next 1st time")
print(next(x))
print("executing next 2nd time")
print(next(x))
print("executing send 1st time")
print(x.send(10))
The output is:
executing next 1st time
row 35
row 37
Row 40
a
executing next 2nd time
row 42
The message is None
row 44
row 50
Row 51
row 37
Row 40
b
executing send 1st time
row 42
The message is 10
row 44
row 47, count = 10
Row 51
row 37
Row 40
k
What I don't understand is what happens before "executing send 1st time"
is printed. b
has just been output by the program, presumably through the message = yield objects[count]
row in infinite_looper
. But then, the value of message is changed to 10
from None
even though message = yield objects[count]
has already been executed! My only theory is that the yield keyword works in such a way that the execution "stays" on its row after it's been executed, and a send
statement to the looper can make the same row (in this case message = yield objects[count]
) execute again. Otherwise, we would have:
executing send 1st time
row 42
The message is **None**
Is this a correct theory? More details on how this works?
Upvotes: 0
Views: 857
Reputation: 282138
But then, the value of message is changed to
10
fromNone
even thoughmessage = yield objects[count]
has already been executed!
No. A value has been yielded, but until the send
call, the value of the yield objects[count]
expression has not been determined or assigned to message
. The generator's execution is suspended midway through execution of the line. (Remember that the value of a yield
expression is not the same as the value it yields.)
The x.send(10)
call causes the yield
expression to take value 10
, and that value is what is assigned to message
.
Upvotes: 5