Slide 1

Slide 1 text

A Gentle Introduction to Generators Coroutines and

Slide 2

Slide 2 text

Hello! Hacker/Programmer @ WalletKit, Inc. Open Source Enthusiast Python Fanboy @kirang89 http://kirang.in

Slide 3

Slide 3 text

Generators Coroutines

Slide 4

Slide 4 text

Let’s back up a bit

Slide 5

Slide 5 text

Functions Takes some input Returns some output (or flow of control) Stateless

Slide 6

Slide 6 text

Now consider a new type of function Pretty much the same (Well, almost) Remembers state after returning flow of control Instead of returning, it yields some output

Slide 7

Slide 7 text

yield = return + sorcery* * It’s not all that magical from a computer’s perspective

Slide 8

Slide 8 text

Generator Functions a.k.a Generators Functions that ‘yield’ are called

Slide 9

Slide 9 text

Coz they’re Why are Generators awesome? Lazy

Slide 10

Slide 10 text

def infinite_seq(): i = 0 while True: yield i i = i +1 https://projecteuler.net/problem=10 OR

Slide 11

Slide 11 text

Example

Slide 12

Slide 12 text

def fibonacci_gen(): a, b = 0, 1 while True: yield b a, b = b, a + b

Slide 13

Slide 13 text

>>> f = fibonacci_gen() >>> type(f) >>> f

Slide 14

Slide 14 text

Print first 5 terms of the fibonacci series f = fibonacci_gen() print(next(f)) # Prints 1 print(next(f)) # Prints 1 print(next(f)) # Prints 2 print(next(f)) # Prints 3 print(next(f)) # Prints 5

Slide 15

Slide 15 text

Using Generators - Generator Functions - Generator Expressions

Slide 16

Slide 16 text

def even_range(n): for i in range(n): if i % 2 == 0: yield i vs even_range_10 = (a for a in range(10) if a % 2 ==0)

Slide 17

Slide 17 text

Performance ? Memory Usage ?

Slide 18

Slide 18 text

kiran:~/ $ python -m timeit "s=[a for a in range(1000000)]” 10 loops, best of 3: 61.3 msec per loop 70 MB kiran:~/ $ python -m timeit "s=(a for a in range(1000000))" 10 loops, best of 3: 16.4 msec per loop ~66 MB kiran:~/ $ python -m timeit "s=(a for a in xrange(1000000))" 1000000 loops, best of 3: 0.802 usec per loop ~3.4 MB

Slide 19

Slide 19 text

Generators Coroutines

Slide 20

Slide 20 text

Co-operative Multitasking/Communication via Enhanced Generators

Slide 21

Slide 21 text

Enhanced ? Allow values/exceptions to be passed as arguments when a generator resumes

Slide 22

Slide 22 text

yield as a keyword yield as an expression vs

Slide 23

Slide 23 text

Receive a value value = (yield) Send a value coroutine.send(data) Close coroutine.close()

Slide 24

Slide 24 text

Example

Slide 25

Slide 25 text

def match(pattern): print('Looking for ' + pattern) try: while True: s = (yield) if pattern in s: print(s) except GeneratorExit: print("Done")

Slide 26

Slide 26 text

>>> matcher = match('python') >>> matcher.send(None) Looking for python >>> matcher.send('Hello World') >>> matcher.send('python is awesome!') python is awesome! >>> matcher.close() Done

Slide 27

Slide 27 text

Let’s look at a bit more awesome example

Slide 28

Slide 28 text

def word_count(): wc = 0 try: while True: _ = (yield) wc = wc + 1 except GeneratorExit: print "Word Count: ", wc pass def match(pattern, counter): print('Looking for ' + pattern) try: while True: s = (yield) if pattern in s: counter.send(None) except GeneratorExit: counter.close() print("Done") def parse(file, matcher): f = open('sampleset.txt', 'r') for line in f.readlines(): for word in line.split(' '): matcher.send(word) matcher.close()

Slide 29

Slide 29 text

counter = word_count() counter.send(None) matcher = match('python', counter) matcher.send(None) parse('sampleset.txt', matcher)

Slide 30

Slide 30 text

We’ve not even scratched the surface!

Slide 31

Slide 31 text

Resources - PEP 255 (Generators) - PEP 289 (Generator Expressions) - PEP 342 (Coroutines) - http://www.dabeaz.com/coroutines/

Slide 32

Slide 32 text

Thank you !