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))
su
is the generator object itself. If you want to get the current value of total
at any point you need to make it yield it, but you can't use next()
because this will make term
be None
which will cause an error. Instead, you need to use .send(0)
:
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.send(0))
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.