forked from yasoob/intermediatePython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcoroutines.html
More file actions
108 lines (98 loc) · 7.05 KB
/
Copy pathcoroutines.html
File metadata and controls
108 lines (98 loc) · 7.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Coroutines</title>
<link rel="stylesheet" href="_static/epub.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
</head>
<body role="document">
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="function_caching.html" title="Function caching"
accesskey="N">next</a></li>
<li class="right" >
<a href="targeting_python_2_3.html" title="Targeting Python 2+3"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Python Tips 0.1 documentation</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="body" role="main">
<div class="section" id="coroutines">
<h1>Coroutines</h1>
<p>Coroutines are similar to generators with a few differences. The main
differences are:</p>
<ul class="simple">
<li>generators are data producers</li>
<li>coroutines are data consumers</li>
</ul>
<p>First of all let’s review the generator creation process. We can make
generators like this:</p>
<div class="code python highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">fib</span><span class="p">():</span>
<span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">a</span>
<span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span>
</pre></div>
</div>
<p>We then commonly use it in a <code class="docutils literal"><span class="pre">for</span></code> loop like this:</p>
<div class="code python highlight-python"><div class="highlight"><pre><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">fib</span><span class="p">():</span>
<span class="k">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
</pre></div>
</div>
<p>It is fast and does not put a lot of pressure on memory because it
<strong>generates</strong> the values on the fly rather then storing them in a list.
Now if we use <code class="docutils literal"><span class="pre">yield</span></code> in the above example more generally we get a
coroutine. Coroutines consume values which are sent to it. A very basic
example would be a <code class="docutils literal"><span class="pre">grep</span></code> alternative in Python:</p>
<div class="code python highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">grep</span><span class="p">(</span><span class="n">pattern</span><span class="p">):</span>
<span class="k">print</span> <span class="s">"Searching for </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">pattern</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="p">(</span><span class="k">yield</span><span class="p">)</span>
<span class="k">if</span> <span class="n">pattern</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</pre></div>
</div>
<p>Wait! What does <code class="docutils literal"><span class="pre">yield</span></code> return? Well we have turned it into a
coroutine. It does not contain any value innitially instead we supply it
values externally. We supply values by using the <code class="docutils literal"><span class="pre">.send()</span></code> method.
Here is an example:</p>
<div class="code python highlight-python"><div class="highlight"><pre><span class="n">search</span> <span class="o">=</span> <span class="n">grep</span><span class="p">(</span><span class="s">'coroutine'</span><span class="p">)</span>
<span class="n">search</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="c"># Output: Searching for coroutine</span>
<span class="n">search</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">"I love you"</span><span class="p">)</span>
<span class="n">search</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">"Don't you love me?"</span><span class="p">)</span>
<span class="n">search</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">"I love coroutines instead!"</span><span class="p">)</span>
<span class="c"># Output: I love coroutines instead!</span>
</pre></div>
</div>
<p>The sent values are accessed by yield. Why did we run <code class="docutils literal"><span class="pre">.next()</span></code>? It is
done to start the coroutine. Just like <code class="docutils literal"><span class="pre">generators</span></code> coroutines do not
start the function immediately. Instead they run it in response to
<code class="docutils literal"><span class="pre">.next()</span></code> and <code class="docutils literal"><span class="pre">.send()</span></code> methods. Therefore you have to run
<code class="docutils literal"><span class="pre">.next()</span></code> so that the execution advances to the <code class="docutils literal"><span class="pre">yield</span></code> expression.</p>
<p>We can close a coroutine by calling the <code class="docutils literal"><span class="pre">.close()</span></code> method. Like:</p>
<div class="code python highlight-python"><div class="highlight"><pre><span class="n">search</span> <span class="o">=</span> <span class="n">grep</span><span class="p">(</span><span class="s">'coroutine'</span><span class="p">)</span>
<span class="c"># ...</span>
<span class="n">search</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>There is a lot more to <code class="docutils literal"><span class="pre">coroutines</span></code>. I suggest you check out <a class="reference external" href="http://www.dabeaz.com/coroutines/Coroutines.pdf">this
awesome
presentation</a><span class="link-target"> [http://www.dabeaz.com/coroutines/Coroutines.pdf]</span> by
David Beazley.</p>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer" role="contentinfo">
© Copyright 2015, Muhammad Yasoob Ullah Khalid.
</div>
</body>
</html>