Reputation: 315
I'm learning about Coroutine but it work strange that I can't understand... Here's the source
@coroutine
def printer():
tmp=(yield)
print tmp
def sender(coru):
coru.send("hello")
print "I'm sender"
if __name__=="__main__":
coru=printer()
sender(coru)
print "I'm master"
shows
hello
StopItertationError @ coru.send("hello")
while,
@coroutine
def printer():
while 1:
tmp=(yield)
print tmp
def sender(coru):
coru.send("hello")
print "I'm sender"
if __name__=="__main__":
coru=printer()
sender(coru)
print "I'm master"
shows
hello
I'm sender
I'm master
correctly.
So I'm wondering
why coroutine always work with the loops and why the first example rise error
I heared about 'yield from' syntax at version 3.3. Is that help to make the first one work?
I know every coroutine function work equivalently unlike the subroutines.
but then, I think, after the Printer function ends, the program should be terminated without returning to Sender.
but it does. doesn't it means that sender superior to printer? what is the difference between subroutine and coroutine then.
thanks for reading and I really appreciate if you enlight me:)
Upvotes: 4
Views: 567
Reputation: 880269
When a generator (like printer
) ends, it raises a StopIteration exception.
When Python executes
coru.send("hello")
it jumps to
tmp = (yield)
and assigns "hello" to tmp
. It then executes the next line:
print tmp
and then the generator ends, thus raising the StopIteration
exception.
If, on the other hand, you do not allow printer
to end (by using a while 1
loop) then the StopIteration
exception is never raised. Instead execution (in printer
) continues until the next yield
expression is reached:
tmp = (yield)
The send
method returns the value of that yield
expression (in this case, None
). At this point, Python has once again returned to the sender
function and next executes
print "I'm sender"
The purpose of the yield from
syntax is to make it easier to refactor generators (intended to be used with send
and throw
) into subgenerators. See PEP380 and What's New in Python3.
It doesn't change the StopIteration behavior.
Upvotes: 5
Reputation: 6797
This is a very nice introduction to coroutines :
http://www.dabeaz.com/coroutines/
In particular, you can have a look at :
http://www.dabeaz.com/coroutines/grep.py
and (exemple @coroutine implementation) :
http://www.dabeaz.com/coroutines/coroutine.py
Upvotes: 2