Monday, April 16, 2007

Notes on generators, yield expressions, and order of execution

I was messing around with the use of yield as an expression, the new feature in Python 2.5, and I got a little tripped in small cases of order with how you need to iterate over the generator and when you call send(), etc. I just thought I would post this example to make anyone passively reading aware of the ordering.


>>> def g():
... print 1
... print 2, (yield)
... print 3
...
>>> gen = g()
>>> gen.next()
1
2
>>> gen.send(0)
0
3
Traceback (most recent call last):
File "", line 1, in
StopIteration
>>>

2 comments:

Jack said...

Each of the print arguments is evaluated left-to-right just before they are needed. If you think of the '(yield)' as '(yield(None))' it might read easier [NB: those extra parens are just grouping and not a function call!]

Here's a similar situation using functions instead:


>>> def a():
... print "A",
... return "ret_A"
...
>>> def b():
... print "B",
... return "ret_B"
...
>>> print 1, a(), 2, b(), 3
1 A ret_A 2 B ret_B 3

Anonymous said...

WOW, so when they said generators halt evaluation at yield, they REALLY mean it!

I write here about programming, how to program better, things I think are neat and are related to programming. I might write other things at my personal website.

I am happily employed by the excellent Caktus Group, located in beautiful and friendly Carrboro, NC, where I work with Python, Django, and Javascript.

Blog Archive