Free AI web copilot to create summaries, insights and extended knowledge, download it at here
11038
Abstract
'builtins'</span>: <module <span class="hljs-string">'builtins'</span> (built-<span class="hljs-keyword">in</span>)>, <span class="hljs-string">'file'</span>: <span class="hljs-string">'/opt/coding/python/tutorials/app_parser.py'</span>, <span class="hljs-string">'cached'</span>: <span class="hljs-keyword">None</span>, <span class="hljs-string">'words_parser'</span>: <module <span class="hljs-string">'words_parser'</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'/opt/coding/python/tutorials/words_parser.py'</span>>}</pre></div><p id="9d8f">You can see that the imported module <i>words_parser</i> is part of the importing module’s global symbol table.</p><h1 id="2f16">What is “from import” in Python?</h1><p id="a1b0">In the previous section we have seen how to import a module using the <b>import statement</b>.</p><p id="27cb">We have also seen that after doing that the name of the <b>imported module</b> was added to the global symbol table of the importing module.</p><p id="e896">There is also another way to write import statements in Python: using the <b>from import</b> statement.</p><div id="6750"><pre><span class="hljs-keyword">from</span> words_parser <span class="hljs-keyword">import</span> select_word, get_unique_letters</pre></div><p id="1d36">This time we have imported the functions defined in the <i>words_parser</i> module instead of the module itself.</p><p id="714e">Let’s see how the global symbol table of the importing module looks like:</p><div id="5c2a"><pre>The <span class="hljs-keyword">global</span> symbol <span class="hljs-keyword">table</span> <span class="hljs-keyword">of</span> the importing module <span class="hljs-keyword">is</span>: {<span class="hljs-string">'name'</span>: <span class="hljs-string">'main'</span>, <span class="hljs-string">'doc'</span>: <span class="hljs-keyword">None</span>, <span class="hljs-string">'package'</span>: <span class="hljs-keyword">None</span>, <span class="hljs-string">'loader'</span>: <_frozen_importlib_external.SourceFileLoader <span class="hljs-keyword">object</span> at <span class="hljs-number">0x7fe940165730</span>>, <span class="hljs-string">'spec'</span>: <span class="hljs-keyword">None</span>, <span class="hljs-string">'annotations'</span>: {}, <span class="hljs-string">'builtins'</span>: <module <span class="hljs-string">'builtins'</span> (built-<span class="hljs-keyword">in</span>)>, <span class="hljs-string">'file'</span>: <span class="hljs-string">'/opt/coding/python/tutorials/app_parser.py'</span>, <span class="hljs-string">'cached'</span>: <span class="hljs-keyword">None</span>, <span class="hljs-string">'select_word'</span>: <<span class="hljs-keyword">function</span> select_word at <span class="hljs-number">0x7fe94026a8b0</span>>, <span class="hljs-string">'get_unique_letters'</span>: <<span class="hljs-keyword">function</span> get_unique_letters at <span class="hljs-number">0x7fe9402d35e0</span>>}</pre></div><p id="851e">This time we don’t see the <i>words_parser</i> module in the global symbol table but we see the two functions we have imported: <i>select_word</i> and <i>get_unique_letters</i>.</p><p id="5241">Do you see the difference compared to the previous import statement?</p><p id="9f61">At this point when calling the functions part of the module you won’t have to use the dot notation (<i>module.function</i>), you can simply use the name of the functions:</p><div id="7e3e"><pre>words = <span class="hljs-selector-attr">[<span class="hljs-string">"module"</span>, <span class="hljs-string">"python"</span>, <span class="hljs-string">"symbol"</span>, <span class="hljs-string">"table"</span>]</span>
selected_word = <span class="hljs-built_in">select_word</span>(words)
<span class="hljs-function"><span class="hljs-title">print</span><span class="hljs-params">(f<span class="hljs-string">"The word selected is: {selected_word}"</span>)</span></span></pre></div><div id="a985"><pre><span class="hljs-variable">word</span> = <span class="hljs-string">"programming"</span>
<span class="hljs-variable">unique_letters</span> = <span class="hljs-function"><span class="hljs-title">get_unique_letters</span>(<span class="hljs-variable">word</span>)</span>
<span class="hljs-function"><span class="hljs-title">print</span>(<span class="hljs-variable">f</span><span class="hljs-string">"The letters of the word {word} without including duplicates are: {unique_letters}"</span>)</span></pre></div><div id="3aaa"><pre>[output]
The <span class="hljs-built_in">word</span> selected <span class="hljs-keyword">is</span>: table
The letters <span class="hljs-keyword">of</span> <span class="hljs-keyword">the</span> <span class="hljs-built_in">word</span> programming <span class="hljs-keyword">without</span> including duplicates are: imnagpro</pre></div><p id="d5c2">It’s also possible to import all the names defined in our module using the following syntax:</p><div id="f63b"><pre><span class="hljs-keyword">from</span> words_parser <span class="hljs-keyword">import</span> *</pre></div><p id="be51">At the same time this is not a suggested approach considering that <b>it’s a good programming practice to be as specific as possible in the code you write</b>.</p><p id="93cc">When you use the * in your import statements it’s not clear what you are importing in your program and what your intentions are.</p><p id="8b8c">In other words this makes your code harder to read for other developers.</p><h1 id="040a">What is “import as” in Python?</h1><p id="be95">When importing a Python module you can also import it with a <b>different name</b> that you can use in your program when referring to that module.</p><p id="d9fd">Here is an example:</p><div id="9239"><pre><span class="hljs-meta">>>> </span><span class="hljs-keyword">import</span> words_parser <span class="hljs-keyword">as</span> wp
<span class="hljs-meta">>>> </span><span class="hljs-built_in">globals</span>()
{<span class="hljs-string">'name'</span>: <span class="hljs-string">'main'</span>, <span class="hljs-string">'doc'</span>: <span class="hljs-literal">None</span>, <span class="hljs-string">'package'</span>: <span class="hljs-literal">None</span>, <span class="hljs-string">'loader'</span>: <<span class="hljs-keyword">class</span> <span class="hljs-string">'_frozen_importlib.BuiltinImporter'</span>>, <span class="hljs-string">'spec'</span>: <span class="hljs-literal">None</span>, <span class="hljs-string">'annotations'</span>: {}, <span class="hljs-string">'builtins'</span>: <module <span class="hljs-string">'builtins'</span> (built-<span class="hljs-keyword">in</span>)>, <span class="hljs-string">'wp'</span>: <module <span class="hljs-string">'words_parser'</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'/opt/coding/python/tutorials/words_parser.py'</span>>}</pre></div><p id="e244">You can see that the name <i>wp</i> is added to the symbol table instead of <i>words_parser</i>.</p><p id="dc39">After importing the <i>words_parser</i> module as <i>wp</i> we can use <i>wp</i> to call the functions defined in the module.</p><div id="8443"><pre>wp<span class="hljs-selector-class">.select_word</span>()
wp<span class="hljs-selector-class">.get_unique_letters</span>()</pre></div><p id="c8b8">You can also use the <b>as keyword</b> with <b>from import</b>.</p><div id="404e"><pre><span class="hljs-keyword">from</span> words_parser <span class="hljs-keyword">import</span> select_word <span class="hljs-keyword">as</span> sw
<span class="hljs-keyword">from</span> words_parser <span class="hljs-keyword">import</span> get_unique_letters <span class="hljs-keyword">as</span> guq</pre></div><div id="1248"><pre>words = <span class="hljs-selector-attr">[<span class="hljs-string">"module"</span>, <span class="hljs-string">"python"</span>, <span class="hljs-string">"symbol"</span>, <span class="hljs-string">"table"</span>]</span>
selected_word = <span class="hljs-built_in">sw</span>(words)
<span class="hljs-function"><span class="hljs-title">print</span><span class="hljs-params">(f<span class="hljs-string">"The word selected is: {selected_word}"</span>)</span></span></pre></div><div id="f0cc"><pre>word = <span class="hljs-string">"programming"</span>
unique_letters = gu<span class="hljs-string">q(word)</span>
<span class="hljs-keyword">print</span>(f<span class="hljs-string">"The letters of the word {word} without including duplicates are: {unique_letters}"</span>)</pre></div><p id="d4a3">This is not very readable so it’s something you might not want to do.</p><p id="23fe">At the same time it’s good for you to be aware of all the options you have available when importing Python modules.</p><h1 id="f8dc">Where Does Python Search For Modules?</h1><p id="acff">In this example we have imported a module we have created in the current directory.</p><p id="4aad">But, how does the Python interpreter know how to import modules that are located in different parts of the filesystem?</p><p id="53d5">For example, if I execute the following import it works fine:</p><div id="a1a9"><pre><span class="hljs-meta">>>> </span><span class="hljs-keyword">import</span> os
<span class="hljs-meta">>>> </span><span class="hljs-built_in">globals</span>()
{<span class="hljs-string">'name'</span>: <span class="hljs-string">'main'</span>, <span class="hljs-string">'doc'</span>: <span class="hljs-literal">None</span>, <span class="hljs-string">'package'</span>: <span class="hljs-literal">None</span>, <span class="hljs-string">'loader'</span>: <<span class="hljs-keyword">class</span> <span class="hljs-string">'_frozen_importlib.BuiltinImporter'</span>>, <span class="hljs-string">'spec'</span>: <span class="hljs-literal">None</span>, <span class="hljs-string">'annotations'</span>: {}, <span class="hljs-string">'builtins'</span>: <module <span class="hljs-string">'builtins'</span> (built-<span class="hljs-keyword">in</span>)>, <span class="hljs-string">'os'</span>: <module <span class="hljs-string">'os'</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/os.py'</span>>}</pre></div><p id="a904">In this specific case the Python interpreter knows that the <b>os module</b> can be imported from /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/os.py.</p><p id="5dab"><b>Note</b>: This directory depends on your operating system and on your Python installation.</p><p id="4693">But, how does the Python interpreter know where to find the module os.py?</p><p id="a010"><b>When importing a module Python looks for a built-in module with that name first. Then it looks for modules in the list of directories part of the PYTHONPATH (the value of the variable sys.path). For example i
Options
f you import the module xyz Python looks for xyz.py in those directories. The first element in the PYTHONPATH list is an empty directory that represents the current directory.</b></p><p id="72c9">Below you can see the list of directories part of the PYTHONPATH on my machine:</p><div id="3577"><pre><span class="hljs-operator">>>></span> <span class="hljs-keyword">import</span> sys
<span class="hljs-operator">>>></span> sys.path
['', '<span class="hljs-regexp">/Library/</span><span class="hljs-type">Developer</span><span class="hljs-regexp">/CommandLineTools/</span><span class="hljs-type">Library</span><span class="hljs-regexp">/Frameworks/</span><span class="hljs-type">Python3</span>.framework<span class="hljs-regexp">/Versions/</span><span class="hljs-number">3.8</span><span class="hljs-regexp">/lib/</span>python38.zip', '<span class="hljs-regexp">/Library/</span><span class="hljs-type">Developer</span><span class="hljs-regexp">/CommandLineTools/</span><span class="hljs-type">Library</span><span class="hljs-regexp">/Frameworks/</span><span class="hljs-type">Python3</span>.framework<span class="hljs-regexp">/Versions/</span><span class="hljs-number">3.8</span><span class="hljs-regexp">/lib/</span>python3.<span class="hljs-number">8</span>', '<span class="hljs-regexp">/Library/</span><span class="hljs-type">Developer</span><span class="hljs-regexp">/CommandLineTools/</span><span class="hljs-type">Library</span><span class="hljs-regexp">/Frameworks/</span><span class="hljs-type">Python3</span>.framework<span class="hljs-regexp">/Versions/</span><span class="hljs-number">3.8</span><span class="hljs-regexp">/lib/</span>python3.<span class="hljs-number">8</span><span class="hljs-regexp">/lib-dynload', '/</span>opt<span class="hljs-regexp">/coding/</span>python<span class="hljs-regexp">/tutorials/</span>python<span class="hljs-operator">-</span>env<span class="hljs-regexp">/lib/</span>python3.<span class="hljs-number">8</span><span class="hljs-operator">/</span>site<span class="hljs-operator">-</span>packages']
<span class="hljs-operator">>>></span> <span class="hljs-built_in">type</span>(sys.path)
<span class="hljs-operator"><</span><span class="hljs-keyword">class</span> '<span class="hljs-title class_">list</span>'></pre></div><p id="ef88"><b>Note</b>: the directories in the PYTHONPATH also depend on your Python installation.</p><p id="4578">In the next sections we will see:</p><ul><li>how to find the location of the file for a specific module.</li><li>how to add more directories to the PYTHONPATH.</li></ul><h1 id="a016">How Can You Find the Location of a Python Module?</h1><p id="602d">Is there a quick way to find out where the file for a module is located on the filesystem?</p><p id="94e6">The answer is yes!</p><p id="3157">Python modules provide a string attribute called <b>file</b> that contains the filesystem location of the module.</p><p id="793d">Let’s test it with our custom module…</p><div id="0b6a"><pre><span class="hljs-meta">>>> </span><span class="hljs-keyword">import</span> words_parser
<span class="hljs-meta">>>> </span>words_parser.file
<span class="hljs-string">'/opt/coding/python/tutorials/words_parser.py'</span>
<span class="hljs-meta">>>> </span><span class="hljs-built_in">type</span>(words_parser.file)
<<span class="hljs-keyword">class</span> <span class="hljs-string">'str'</span>></pre></div><p id="873f">And also with the Python os built-in module…</p><div id="1989"><pre><span class="hljs-operator">>>></span> <span class="hljs-keyword">import</span> os
<span class="hljs-operator">>>></span> os.file
'<span class="hljs-regexp">/Library/</span><span class="hljs-type">Developer</span><span class="hljs-regexp">/CommandLineTools/</span><span class="hljs-type">Library</span><span class="hljs-regexp">/Frameworks/</span><span class="hljs-type">Python3</span>.framework<span class="hljs-regexp">/Versions/</span><span class="hljs-number">3.8</span><span class="hljs-regexp">/lib/</span>python3.<span class="hljs-number">8</span><span class="hljs-operator">/</span>os.py'</pre></div><p id="cb40">That’s quite useful!</p><h1 id="c725">How Can You Update the PYTHONPATH?</h1><p id="2660">A few sections above we have seen how to import the <i>words_parser</i> module simply by being in the same directory where we have created the file for that module.</p><p id="b507">The import was working because the Python interpreter was looking for that module in the current directory.</p><p id="c56d">Now let’s do a little experiment…</p><p id="db77">Create a directory called <i>modules_tutorial</i> and move the file <i>words_parser.py</i> to that directory.</p><div id="61d4"><pre><span class="hljs-meta prompt_"> </span><span class="language-bash"><span class="hljs-built_in">mkdir</span> modules_tutorial</span>
<span class="hljs-meta prompt_"> </span><span class="language-bash"><span class="hljs-built_in">mv</span> words_parser.py modules_tutorial</span></pre></div><p id="26a0">Now, don’t change directory and open the Python shell from the current directory that is the parent directory of the directory modules_tutorial.</p><div id="2d0f"><pre>>>> <span class="hljs-keyword">import</span> words_parser
Traceback (most recent <span class="hljs-keyword">call</span> last):
<span class="hljs-keyword">File</span> <span class="hljs-string">"<stdin>"</span>, line <span class="hljs-number">1</span>, <span class="hljs-keyword">in</span> <<span class="hljs-keyword">module</span>>
ModuleNotFoundError: No <span class="hljs-keyword">module</span> <span class="hljs-keyword">named</span> <span class="hljs-string">'words_parser'</span></pre></div><p id="e7e5">When we import the <i>words_parser</i> module the Python interpreter cannot find it because we have moved it to a different directory.</p><p id="bc59">One way to make this work is to update the PYTHONPATH.</p><p id="c1d1">As explained before the PYTHONPATH is a list of directories stored in <b>sys.path</b>.</p><p id="9091">Considering that <i>sys.path</i> is a list we can use the <a href="https://codefather.tech/blog/python-list-methods/">list append method</a> to add directories to it.</p><p id="1b98">Let’s try to add the new directory we have created (modules_tutorial) to the Python path:</p><div id="907d"><pre><span class="hljs-operator">>>></span> sys.path.append('<span class="hljs-regexp">/opt/</span>coding<span class="hljs-regexp">/python/</span>tutorials<span class="hljs-operator">/</span>modules_tutorial')
<span class="hljs-operator">>>></span> sys.path
['', '<span class="hljs-regexp">/Library/</span><span class="hljs-type">Developer</span><span class="hljs-regexp">/CommandLineTools/</span><span class="hljs-type">Library</span><span class="hljs-regexp">/Frameworks/</span><span class="hljs-type">Python3</span>.framework<span class="hljs-regexp">/Versions/</span><span class="hljs-number">3.8</span><span class="hljs-regexp">/lib/</span>python38.zip', '<span class="hljs-regexp">/Library/</span><span class="hljs-type">Developer</span><span class="hljs-regexp">/CommandLineTools/</span><span class="hljs-type">Library</span><span class="hljs-regexp">/Frameworks/</span><span class="hljs-type">Python3</span>.framework<span class="hljs-regexp">/Versions/</span><span class="hljs-number">3.8</span><span class="hljs-regexp">/lib/</span>python3.<span class="hljs-number">8</span>', '<span class="hljs-regexp">/Library/</span><span class="hljs-type">Developer</span><span class="hljs-regexp">/CommandLineTools/</span><span class="hljs-type">Library</span><span class="hljs-regexp">/Frameworks/</span><span class="hljs-type">Python3</span>.framework<span class="hljs-regexp">/Versions/</span><span class="hljs-number">3.8</span><span class="hljs-regexp">/lib/</span>python3.<span class="hljs-number">8</span><span class="hljs-regexp">/lib-dynload', '/</span>opt<span class="hljs-regexp">/coding/</span>python<span class="hljs-regexp">/tutorials/</span>python<span class="hljs-operator">-</span>env<span class="hljs-regexp">/lib/</span>python3.<span class="hljs-number">8</span><span class="hljs-regexp">/site-packages', '/</span>opt<span class="hljs-regexp">/coding/</span>python<span class="hljs-regexp">/tutorials/</span>modules_tutorial']</pre></div><p id="a318">As you can see the new directory we have created has been appended at the end of the <b>sys.path</b> list.</p><p id="ca37">Try to import the <i>words_parser</i> module again…</p><div id="2b28"><pre><span class="hljs-meta prompt_">>>></span> <span class="language-python"><span class="hljs-keyword">import</span> words_parser</span>
<span class="hljs-meta prompt_">>>></span> <span class="language-python">words_parser.file</span>
'/opt/coding/python/tutorials/modules_tutorial/words_parser.py'</pre></div><p id="adfe">This time the import is successful.</p><p id="445c"><b>Note</b>: the change to sys.path is lost if you exit from the Python shell and then you reopen it. So if you want to persist it you have to add it to your Python program.</p><h1 id="7030">Using the dir() Function with Python Modules</h1><p id="968e">The <b>dir() built-in function</b> allows to see which names are defined in a specific Python module.</p><p id="ea74">Here is the output of the dir() function when we apply it to our <i>words_parser</i> module.</p><div id="8d29"><pre><span class="hljs-meta">>>> </span><span class="hljs-keyword">import</span> words_parser
<span class="hljs-meta">>>> </span><span class="hljs-built_in">dir</span>(words_parser)
[<span class="hljs-string">'builtins'</span>, <span class="hljs-string">'cached'</span>, <span class="hljs-string">'doc'</span>, <span class="hljs-string">'file'</span>, <span class="hljs-string">'loader'</span>, <span class="hljs-string">'name'</span>, <span class="hljs-string">'package'</span>, <span class="hljs-string">'spec'</span>, <span class="hljs-string">'get_unique_letters'</span>, <span class="hljs-string">'random'</span>, <span class="hljs-string">'select_word'</span>]</pre></div><p id="87c4">You can see that some names are set by default considering that we haven’t set them (e.g. builtins, name, package, etc….).</p><p id="18d0">Other names are related to the code we have added to the <i>words_parser</i> module:</p><ul><li>the random module imported at the beginning of the <i>words_parser</i> module.</li><li>the select_word() function.</li><li>the get_unique_letters() function.</li></ul><h1 id="bb6d">Conclusion</h1><p id="633c">In this tutorial, we went through concepts that will help you understand, create, and use Python modules.</p><p id="e30a">You now know what modules are, how to create them, how to use them, how to import them, how to find their location, and how to suggest new locations for modules to the Python interpreter.</p><p id="d733">And now it’s time for you to put this knowledge into practice!</p></article></body>