 <p>Let’s look at three common reasons for writing inner functions.</p> <h2>1. Closures and Factory Functions</h2> <p>The value in the enclosing scope is remembered even when the variable goes out of scope or the function itself is removed from the current namespace.</p> <pre><code>def print_msg(msg): """This is the outer enclosing function""" def printer(): """This is the nested function""" print(msg) return printer # this got changed </code></pre> <p>Now let's try calling this function. </p> <pre><code>&gt;&gt;&gt; another = print_msg("Hello") &gt;&gt;&gt; another() Hello </code></pre> <p>That's unusual. The <code>print_msg()</code> function was called with the string <code>"Hello"</code> and the returned function was bound to the name <code>another</code>. On calling <code>another()</code>, the message was still remembered although we had already finished executing the <code>print_msg()</code> function. This technique by which some data (<code>"Hello"</code>) gets attached to the code is called closure in Python.</p> When To Use Closures? <p>So what are closures good for? Closures can avoid the use of global values and provides some form of data hiding. It can also provide an object oriented solution to the problem. When there are few methods (one method in most cases) to be implemented in a class, closures can provide an alternate and more elegant solutions. <a href="http://href=%22http://www.programiz.com/python-programming/closure%22" rel="nofollow">Reference</a></p> <h2>2. Encapsulation :</h2> <p>General concept of encapsulation is to hide and protect inner world from Outer one, Here inner functions can be accessed only inside the outer one and are protected from anything happening outside of the function.</p> <h2>3. Keepin’ it DRY</h2> <p>Perhaps you have a giant function that performs the same chunk of code in numerous places. For example, you might write a function which processes a file, and you want to accept either an open file object or a file name:</p> <pre><code>def process(file_name): def do_stuff(file_process): for line in file_process: print(line) if isinstance(file_name, str): with open(file_name, 'r') as f: do_stuff(f) else: do_stuff(file_name) </code></pre> <p>For more you can refer <a href="https://realpython.com/blog/python/inner-functions-what-are-they-good-for/" rel="nofollow">this</a> blog.</p>