<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://albatross.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 23 Oct 2026 18:44:08 GMT</lastBuildDate><atom:link href="https://albatross.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Coroutines  in Python]]></title><description><![CDATA[The building blocks of asynchronous programming]]></description><link>https://albatross.hashnode.dev/coroutines-in-python</link><guid isPermaLink="true">https://albatross.hashnode.dev/coroutines-in-python</guid><category><![CDATA[Python]]></category><category><![CDATA[asynchronous]]></category><dc:creator><![CDATA[Robin Siwach]]></dc:creator><pubDate>Mon, 30 Jan 2023 10:30:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/CqX6IhVj2TI/upload/73f65391f604d0f15998fb5e137e36be.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Prerequisites: You should know about iterators and how a for loop in Python works behind the scenes. You don’t need to know anything about generators, coroutines, or the</em> <code>yield</code> <em>keyword.</em></p>
<p>Just a quick overview of how a for loop works in Python:</p>
<pre><code class="lang-python">x = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> x:
    print(i)
</code></pre>
<pre><code class="lang-markdown">OUTPUT : 

1
2
3
4
5
</code></pre>
<p>The code above is equivalent to the code given below:</p>
<pre><code class="lang-python">x = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]
y = iter(x)
<span class="hljs-keyword">try</span>:
    <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
        print(next(y))
<span class="hljs-keyword">except</span> StopIteration <span class="hljs-keyword">as</span> e:
    <span class="hljs-keyword">pass</span>
</code></pre>
<pre><code class="lang-plaintext">OUTPUT :
1
2
3
4
5
</code></pre>
<h1 id="heading-what-are-coroutines"><strong>What Are Coroutines?</strong></h1>
<p>Coroutines are basically functions whose execution can be paused/suspended at a particular point, and then we can resume the execution from that same point later whenever we want.</p>
<p>We need a mechanism — or to be more precise, a keyword — by which we can insert a checkpoint and tell the program that we want to pause the execution of the function here and return control to the point it is called from. We’ll resume the execution whenever we want.</p>
<p>In Python, we can pause the execution of a function using the <code>yield</code> keyword.</p>
<p>So here’s where things get interesting :</p>
<ul>
<li><p>We can think of a coroutine as a function that has one or more checkpoints where the execution will be paused and control will be returned to the point where it was called from.</p>
</li>
<li><p>In essence, a coroutine is a function divided into many parts, and we can execute each part of a coroutine as we execute each iteration of a for loop using the <code>next</code> function.</p>
</li>
</ul>
<p>Here’s a basic example :</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func</span>():</span>
    print(<span class="hljs-string">'Function Starts'</span>)

    <span class="hljs-keyword">yield</span>

    print(<span class="hljs-string">'Function Ends'</span>)


<span class="hljs-keyword">try</span>:
    y = func()
    print(type(y))
    next(y)  <span class="hljs-comment"># First part of the function executed</span>
    next(y)  <span class="hljs-comment"># Second part of the function executed</span>

<span class="hljs-keyword">except</span> StopIteration <span class="hljs-keyword">as</span> e:
    <span class="hljs-keyword">pass</span>
</code></pre>
<pre><code class="lang-plaintext">
OUTPUT :
&lt;class 'generator'&gt;
Function Starts
Function Ends
</code></pre>
<p>From the output, we notice a few things:</p>
<ul>
<li><p>First, we need to call the coroutine/function that will give us a generator object.</p>
</li>
<li><p>That generator object will behave similarly to an iterator, but in the case of an iterator, we are traversing over an iterable. With a generator, we’re executing parts of the coroutine.</p>
</li>
<li><p>Just as a <code>StopIteration</code> exception is thrown and caught behind the scenes of a for loop, the same happens in this case when the last part of the coroutine is executed.</p>
</li>
</ul>
<p>Now, this pausing of the function in between is very interesting and opens up some possibilities:</p>
<ul>
<li><p>When the function is paused, we do nothing, which is the case that we just saw.</p>
</li>
<li><p>Suppose a variable is being modified several times in a function and we want the value of that particular variable at a certain checkpoint. Then when we pause that function on that particular checkpoint, it returns the value of that variable.</p>
</li>
</ul>
<p>Let’s see an example:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func</span>():</span>
    x = <span class="hljs-number">5</span>
    print(<span class="hljs-string">'Function Part 1'</span>)

    <span class="hljs-keyword">yield</span> x
    x += <span class="hljs-number">7</span>
    print(<span class="hljs-string">'Function part 2'</span>)

    <span class="hljs-keyword">yield</span> x

    print(<span class="hljs-string">'Function part 3'</span>)


<span class="hljs-keyword">try</span>:
    y = func()
    z = next(y)        <span class="hljs-comment"># Function part 1 executed</span>
    print(z)

    z = next(y)        <span class="hljs-comment"># Function part 2 executed</span>
    print(z)

    z = next(y)        <span class="hljs-comment"># Function part 3 executed and StopIteration exception raised</span>
    print(z)          <span class="hljs-comment"># This print will not be executed</span>

<span class="hljs-keyword">except</span> StopIteration <span class="hljs-keyword">as</span> e:
    <span class="hljs-keyword">pass</span>
</code></pre>
<pre><code class="lang-plaintext">OUTPUT :
Function Part 1
5
Function part 2
12
Function part 3
</code></pre>
<p>Here, the value of <code>x</code> is returned by <code>yield</code> at different checkpoints, as the function execution has been paused.</p>
<p>Whenever we are executing the last part of the function and there is no yield left in the function, after executing that last part, a <code>StopIteration</code> exception will be raised.</p>
<p>Much like when an iterator tries to execute the next function, but there are no more elements left in the iterable, it also raises the <code>StopIteration</code> exception.</p>
<ul>
<li>Suppose we want to send a value (which can be a constant or variable) at a certain checkpoint (i.e. at a certain state of a function). We can also do that using the <code>yield</code> keyword. When we want to send a value, we'll use the <code>send</code> function instead of <code>next</code>.</li>
</ul>
<p>Let’s see an example:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func</span>():</span>
    print(<span class="hljs-string">'Function part 1'</span>)

    x = <span class="hljs-keyword">yield</span>
    print(x)
    print(<span class="hljs-string">'Function part 2'</span>)

    a = <span class="hljs-keyword">yield</span>
    print(a)
    print(<span class="hljs-string">'Function part 3'</span>)


<span class="hljs-keyword">try</span>:

    y = func()

    next(y)            <span class="hljs-comment"># Function part 1 executed, to reach the first yield we used next</span>

    y.send(<span class="hljs-number">6</span>)        <span class="hljs-comment"># Function part 2 executed and value sent 6</span>

    y.send(<span class="hljs-number">12</span>)        <span class="hljs-comment"># Function part 2 executed and value sent 12 and StopIteration raised</span>

<span class="hljs-keyword">except</span> StopIteration <span class="hljs-keyword">as</span> e:
    <span class="hljs-keyword">pass</span>
</code></pre>
<pre><code class="lang-plaintext">OUTPUT :
Function part 1
6
Function part 2
12
Function part 3
</code></pre>
<p>The reason we used <code>next</code> before using <code>send</code> is we can only use <code>send</code> when we are at the <code>yield</code> checkpoint, and <code>yield</code> is on the right side of the expression. So to reach that first <code>yield</code>, we have to use the <code>next</code> function.</p>
<p>Now here comes an interesting application of coroutines. Suppose we want to switch back and forth between two functions as we do in multithreading. In multithreading, until an <code>interrupt</code> is encountered by the OS, it will keep executing. In this case, we can switch whenever we want.</p>
<p>Let’s see an example :</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func1</span>():</span>
    print(<span class="hljs-string">'Function 1 part 1'</span>)

    <span class="hljs-keyword">yield</span>
    print(<span class="hljs-string">'Function 1 part 2'</span>)

    <span class="hljs-keyword">yield</span>
    print(<span class="hljs-string">'Function 1 part 3'</span>)

    <span class="hljs-keyword">yield</span>
    print(<span class="hljs-string">'Function 1 part 4'</span>)

    <span class="hljs-keyword">yield</span>
    print(<span class="hljs-string">'Function 1 part 5'</span>)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func2</span>():</span>
    print(<span class="hljs-string">'Function 2 part 1'</span>)

    <span class="hljs-keyword">yield</span>
    print(<span class="hljs-string">'Function 2 part 2'</span>)

    <span class="hljs-keyword">yield</span>
    print(<span class="hljs-string">'Function 2 part 3'</span>)

    <span class="hljs-keyword">yield</span>
    print(<span class="hljs-string">'Function 2 part 4'</span>)

    <span class="hljs-keyword">yield</span>
    print(<span class="hljs-string">'Function 2 part 5'</span>)


<span class="hljs-keyword">try</span>:

    a = func1()
    b = func2()

    next(a)      <span class="hljs-comment"># Will execute Function 1 part 1</span>
    next(b)      <span class="hljs-comment"># Will execute Function 2 part 1</span>
    next(a)      <span class="hljs-comment"># Will execute Function 1 part 2</span>
    next(a)      <span class="hljs-comment"># Will execute Function 1 part 3</span>
    next(b)      <span class="hljs-comment"># Will execute Function 2 part 2</span>
    next(b)      <span class="hljs-comment"># Will execute Function 2 part 3</span>
    next(b)      <span class="hljs-comment"># Will execute Function 2 part 4</span>
    next(a)      <span class="hljs-comment"># Will execute Function 1 part 4</span>
    next(a)      <span class="hljs-comment"># Will execute Function 1 part 5 and raise StopIteration exception</span>

<span class="hljs-keyword">except</span> StopIteration <span class="hljs-keyword">as</span> e:
    <span class="hljs-keyword">pass</span>
</code></pre>
<pre><code class="lang-plaintext">OUTPUT :
Function 1 part 1
Function 2 part 1
Function 1 part 2
Function 1 part 3
Function 2 part 2
Function 2 part 3
Function 2 part 4
Function 1 part 4
Function 1 part 5
</code></pre>
<p>In this example, we can see that we can switch back and forth between coroutines whenever we want.</p>
<p>So if we write our own custom scheduler that handles the switching between multiple coroutines, we can achieve with single threading what we do with multithreading.</p>
<p>Coroutines have many applications such as concurrency and other programming patterns can also be implemented, like Producer-Consumer or Sender-Receiver in network programming. I’ll be exploring those in upcoming articles.</p>
<p>Coroutines are also the building blocks of many frameworks such as asyncio, twisted, aiohttp. They can also be chained together to make pipelines and solve problems.</p>
]]></content:encoded></item></channel></rss>