yield:
The Python keyword you never bothered to learn
I'm Steve
Web developer at Insync
Part-time link poster at SVI
Hates semicolons
Iterator
>>> class countdown:
... def __init__(self, count):
... self.count = count
... def __iter__(self):
... return self
... def next(self):
... if self.count > 0:
... count = self.count
... self.count -= 1
... return count
... else:
... raise StopIteration()>>> for i in countdown(10):
... print i
...
10
9
8
7
6
5
4
3
2
1
Generator
>>> def countdown(n):
... while n > 0:
... yield n
... n -= 1
>>> for i in countdown(5):
... print i
...
5
4
3
2
1Generator Expressions
>>> (x**2 for x in range(5))
<generator object <genexpr> at 0x105f40be0>
>>>
>>> for i in _:
... print i
...
0
1
4
9
16
>>> sum(x**2 for x in range(5))
30Examples
def cat(*filenames):
for filename in filenames:
for line in open(filename):
yield line
cat("file.a", "file.b", "file.c")def quote(text, prefix=">"):
return "\n".join(
prefix + " " + line
for line in text.split("\n")
)
>>> print quote("""Our acuse cleaned the tofu's
... sense sanely, really hazardous.
...
... A sick trunk mixes one's milky dilemma of simple
... mothers before cheeses without my local library.
""")
> Our acuse cleaned the tofu's
> sense sanely, really hazardous.
>
> A sick trunk mixes one's milky dilemma of simple
> mothers before cheeses without my local library.def process_order(user, order):
if not user.has_enough_funds():
yield "Not enough funds"
if not check_order(order):
yield "Invalid order"
order.charge(user)@app.route('/buy')
def buy():
user = get_user()
order = get_order()
errors = []
if request.method == 'POST':
errors = list(process_order(user, order))
if not errors:
return redirect('/thanks')
return render_template('buy.html', errors=errors)
from contextlib import contextmanager
@contextmanager
def transaction():
try:
session = create_session()
yield session
except:
session.rollback()
else:
session.commit()
with transaction() as session:
session.add(User(name="Steve"))
session.add(User(name="Mark"))

Coroutines

PEP-342: yield as an expression
def fizzbuzz():
try:
while True:
number = (yield)
foo = ""
if number % 3 == 0:
foo += "Fizz"
if number % 5 == 0:
foo += "Buzz"
print foo if foo else number
except GeneratorExit:
print "Bye!"
>>> cor = fizzbuzz()
>>> cor.next() # Prime it!
>>> for x in range(1, 16):
... cor.send(x)
...
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
>>> cor.close()
Bye!def coroutine(func):
def start(*args, **kwargs):
cor = func(*args, **kwargs)
cor.next()
return cor
return start
@coroutine
def fizzbuzz():
...>>> fb = fizzbuzz()
>>> for x in range(1, 6):
... fb.send(x)
...
1
2
Fizz
4
Buzz
>>> fb.close()
Bye!
>>>LET'S CREATE A SLACKBOT https://gist.github.com/marksteve/040c096366795f7c0d77
Dave Beazly's talks on Generators
questions = (
person.ask() for person in room
if person.has_question()
)
answers = (
question.answer() for question in questions
)
if all(answers):
yield next_talkyield:
By Mark Steve Samson
yield:
- 1,316