Help me understand why yield total
doesn't comes out as 0
at the first calling!
Since [sumer] passed though [primer] by @coroutine, [su] already met next() in side of primer right?
So I'm guessing the result of print('EX2-1 -',su)
should be
0
But the real result turns out to be just showing the address of su,
and only after su.send(100)
the value comes out as 100
What am I missing??
from functools import wraps
from inspect import getgeneratorstate
def coroutine(func):
@wraps(func)
def primer(*args, **kwargs):
gen = func()
next(gen)
return gen
return primer
@coroutine
def sumer():
total = 0
term = 0
while True :
term = yield total
print('term recieved')
total += term
su = sumer()
print('EX2-1 -',su)
print(getgeneratorstate(su))
print('EX2-1 -', su.send(100))
Let's go through your code step by step.
The coroutine
decorator is gonna return it's inner function which is primer
and that's it... So after you apply @coroutine
to the sumer
, the sumer
label is now pointing to the primer
function.
Next when you call the primer
function in line su = sumer()
, it will create a coroutine in line gen = func()
then primes it with next(gen)
and returns the primed coroutine.
Up until now su
is pointing to whatever the primer
function returned, which is a generator not the value !
Your problem is exactly here, if the primer
returns next(gen)
you will get 0
. But that 0
is just skipped and your coroutine is now ready to receive values.
Try to change it to:
from functools import wraps
def coroutine(func):
@wraps(func)
def primer(*args, **kwargs):
gen = func()
return next(gen)
return primer
@coroutine
def sumer():
total = 0
while True:
term = yield total
print('term recieved')
total += term
su = sumer()
print('EX2-1 -', su)
It is 0
now but not useful anymore.
Since su
is not the generator anymore, you can't pass it to the getgeneratorstate
and also send value to it. It is an integer now.