{"id":333,"date":"2021-03-30T20:44:21","date_gmt":"2021-03-30T20:44:21","guid":{"rendered":"https:\/\/andrejacobs.org\/?p=333"},"modified":"2022-04-11T20:22:59","modified_gmt":"2022-04-11T20:22:59","slug":"100-days-of-learning-day-22-understanding-the-python-importing-process","status":"publish","type":"post","link":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/","title":{"rendered":"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process"},"content":{"rendered":"\n

Here is my Log book<\/a> entry.<\/p>\n

Code for today<\/a>.<\/p>\n

It has been bugging me for a while now that I seem to hit a Python module \/ package loading issue just when I think I know how it works. Time to learn and explore just how the basics of the loading system works in Python (version 3 and above).<\/p>\n

What are modules and packages?<\/h2>\n

A module<\/code> is any .py source code file. The name of the module is the file name without the extension. For example: the file hello.py is a module and the module name is hello.<\/p>\n

A package<\/code> can be any directory. Before Python 3.3 a directory must have a file named __init__.py<\/code> to be seen as a package. The package name is the directory name.<\/p>\n

What is importing?<\/h2>\n

Importing is the process by which Python code in one module<\/code> is made available to Python code in another module<\/code>.<\/p>\n

An importer<\/code> is an object that does both finding and loading of modules.<\/p>\n

Single module example<\/h2>\n

Let us build up our understanding of how this importing process works by first starting with just a single module<\/code>.<\/p>\n

The project’s root directory is just called project in this example. It contains a file named example.py. Thus this means we have a module named "example".<\/p>\n

# Directory structure\nproject\n    \u2514\u2500\u2500 example.py\n<\/code><\/pre>\n
# example.py\n\nprint(f'This is global scope of example.py. __name__ is: {__name__}')\n\nif __name__ == '__main__':\n    print('This is example.py running')\n    print(f'My __name__ is: {__name__}')\n<\/code><\/pre>\n

Let’s see what happens when we tell the interpreter to load our module.<\/p>\n

$ python example.py\nThis is global scope of example.py. __name__ is: __main__\nThis is example.py running\nMy __name__ is: __main__\n\n$ python -m example\n# Gives the same result\n<\/code><\/pre>\n

Ok so we can see that when the python interpreter loaded the module it set the __name__<\/code> variable to __main__<\/code>. It first ran all the code at the global scope.<\/p>\n

We then have an if<\/code> check to see if the __name__<\/code> is __main__<\/code> and if so then run more code.<\/p>\n

Module importing another module<\/h2>\n

Add another file named module1.py inside the same directory.<\/p>\n

# module1.py\n\nprint(f'This is global scope of module1.py. __name__ is: {__name__}')\n\nif __name__ == '__main__':\n    print('This is module1.py running')\n<\/code><\/pre>\n
project\n    \u251c\u2500\u2500 example.py\n    \u2514\u2500\u2500 module1.py\n<\/code><\/pre>\n

Load and run this new module.<\/p>\n

$ python module1.py\nThis is global scope of module1.py. __name__ is: __main__\nThis is module1.py running\n<\/code><\/pre>\n

Modify example.py to import module1 and load example.py.<\/p>\n

# example.py\n\nprint(f'This is global scope of example.py. __name__ is: {__name__}')\n\nimport module1\n\nif __name__ == '__main__':\n    print('This is example.py running')\n    print(f'My __name__ is: {__name__}')\n<\/code><\/pre>\n
$ python example.py\nThis is global scope of example.py. __name__ is: __main__\nThis is global scope of module1.py. __name__ is: module1\nThis is example.py running\nMy __name__ is: __main__\n<\/code><\/pre>\n

Notice how the value of __name__<\/code> has been changed to module1 when the code from module1.py was loaded and executed as the result of being loaded by another module.<\/p>\n

Also take notice that in this case the if __name__ ...<\/code> code from module1 was not run (as you would expect).<\/p>\n

Key point:<\/strong> The name of the module first loaded and executed by the Python interpreter will be set to __main__<\/code> regardless of what the module’s actual name is.<\/p>\n

Single package example<\/h2>\n

Create a new directory named package1 and add a file named __init__.py<\/code><\/p>\n

project\n    \u251c\u2500\u2500 example.py\n    \u251c\u2500\u2500 module1.py\n    \u2514\u2500\u2500 package1\n        \u251c\u2500\u2500 __init__.py\n<\/code><\/pre>\n
# package1 __init__.py\nprint(f'This is global scope of package1\/__init__.py. __name__ is: {__name__}')\nprint(f'__package__ is: {__package__}')\n<\/code><\/pre>\n

Modify example.py<\/p>\n

...\nprint(f'This is global scope of example.py. __name__ is: {__name__}')\nprint(f'example.py __package__ is: {__package__}')\n\nimport module1\nimport package1\n...\n<\/code><\/pre>\n

Modify module1.py<\/p>\n

...\nprint(f'This is global scope of module1.py. __name__ is: {__name__}')\nprint(f'module1.py __package__ is: {__package__}')\n...\n<\/code><\/pre>\n

Load and run example.py<\/p>\n

$ python example.py\nThis is global scope of example.py. __name__ is: __main__\nexample.py __package__ is: None\nThis is global scope of module1.py. __name__ is: module1\nmodule1.py __package__ is:\nThis is global scope of package1\/__init__.py. __name__ is: package1\n__package__ is: package1\nThis is example.py running\nMy __name__ is: __main__\n<\/code><\/pre>\n

Notice how the package name of example.py is None<\/code> whereas the package name for module1.py is blank (I am guessing this is an empty string ”).<\/p>\n

example.py imported package1 and the loading system found the file named __init__.py<\/code> and executed the code. The name of the package is what we would expect (the name of the directory i.e. package1).<\/p>\n

What happens if we used python -m<\/code> to load and run example.py?<\/p>\n

$ python -m example\nThis is global scope of example.py. __name__ is: __main__\nexample.py __package__ is:\nThis is global scope of module1.py. __name__ is: module1\nmodule1.py __package__ is:\nThis is global scope of package1\/__init__.py. __name__ is: package1\n__package__ is: package1\nThis is example.py running\nMy __name__ is: __main__\n<\/code><\/pre>\n

Can you spot the difference?<\/p>\n

example.py<\/a> ‘s __package__<\/code> is set to None<\/code> when you use python example.py<\/code> where as it is blank when you use the -m<\/code> option to load the module named example.<\/p>\n

Wrap up for tonight<\/h3>\n

I have barely even started scratching the surface of this topic.<\/p>\n

Tomorrow I will be diving more into how this module loading process works in Python.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"

[…]<\/p>\n

Read more →<\/a><\/p>\n","protected":false},"author":2,"featured_media":254,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[37],"tags":[23],"yoast_head":"\n100 Days of Learning: Day 22 \u2013 Understanding the Python importing process - Andr\u00e9 Jacobs<\/title>\n<meta name=\"description\" content=\"Day 22 of 100 complete. Today I am exploring the basics of Python's loading system and learn the difference between a module and a package.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process - Andr\u00e9 Jacobs\" \/>\n<meta property=\"og:description\" content=\"Day 22 of 100 complete. Today I am exploring the basics of Python's loading system and learn the difference between a module and a package.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/\" \/>\n<meta property=\"og:site_name\" content=\"Andr\u00e9 Jacobs\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-30T20:44:21+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-04-11T20:22:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/python-logo-master-v3-TM.png\" \/>\n\t<meta property=\"og:image:width\" content=\"601\" \/>\n\t<meta property=\"og:image:height\" content=\"203\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Jacobs\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@andrejacobs81\" \/>\n<meta name=\"twitter:site\" content=\"@andrejacobs81\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Jacobs\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/\"},\"author\":{\"name\":\"Andr\u00e9 Jacobs\",\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"headline\":\"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process\",\"datePublished\":\"2021-03-30T20:44:21+00:00\",\"dateModified\":\"2022-04-11T20:22:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/\"},\"wordCount\":537,\"publisher\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"keywords\":[\"Python\"],\"articleSection\":[\"100 Days Challenge\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/\",\"url\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/\",\"name\":\"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process - Andr\u00e9 Jacobs\",\"isPartOf\":{\"@id\":\"https:\/\/andrejacobs.org\/#website\"},\"datePublished\":\"2021-03-30T20:44:21+00:00\",\"dateModified\":\"2022-04-11T20:22:59+00:00\",\"description\":\"Day 22 of 100 complete. Today I am exploring the basics of Python's loading system and learn the difference between a module and a package.\",\"breadcrumb\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/andrejacobs.org\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/andrejacobs.org\/#website\",\"url\":\"https:\/\/andrejacobs.org\/\",\"name\":\"Andr\u00e9 Jacobs\",\"description\":\"iOS Development, Electronics, Robotics, Artificial Intelligence, Business and Health\",\"publisher\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/andrejacobs.org\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\",\"name\":\"Andr\u00e9 Jacobs\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg\",\"contentUrl\":\"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg\",\"width\":450,\"height\":450,\"caption\":\"Andr\u00e9 Jacobs\"},\"logo\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/\"},\"sameAs\":[\"https:\/\/andrejacobs.org\",\"https:\/\/www.youtube.com\/channel\/UCzqXvnd_UJ3sAzQkQBD-IVw\"],\"url\":\"https:\/\/andrejacobs.org\/author\/andre\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process - Andr\u00e9 Jacobs","description":"Day 22 of 100 complete. Today I am exploring the basics of Python's loading system and learn the difference between a module and a package.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/","og_locale":"en_GB","og_type":"article","og_title":"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process - Andr\u00e9 Jacobs","og_description":"Day 22 of 100 complete. Today I am exploring the basics of Python's loading system and learn the difference between a module and a package.","og_url":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/","og_site_name":"Andr\u00e9 Jacobs","article_published_time":"2021-03-30T20:44:21+00:00","article_modified_time":"2022-04-11T20:22:59+00:00","og_image":[{"width":601,"height":203,"url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/python-logo-master-v3-TM.png","type":"image\/png"}],"author":"Andr\u00e9 Jacobs","twitter_card":"summary_large_image","twitter_creator":"@andrejacobs81","twitter_site":"@andrejacobs81","twitter_misc":{"Written by":"Andr\u00e9 Jacobs","Estimated reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/#article","isPartOf":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/"},"author":{"name":"Andr\u00e9 Jacobs","@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"headline":"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process","datePublished":"2021-03-30T20:44:21+00:00","dateModified":"2022-04-11T20:22:59+00:00","mainEntityOfPage":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/"},"wordCount":537,"publisher":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"keywords":["Python"],"articleSection":["100 Days Challenge"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/","url":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/","name":"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process - Andr\u00e9 Jacobs","isPartOf":{"@id":"https:\/\/andrejacobs.org\/#website"},"datePublished":"2021-03-30T20:44:21+00:00","dateModified":"2022-04-11T20:22:59+00:00","description":"Day 22 of 100 complete. Today I am exploring the basics of Python's loading system and learn the difference between a module and a package.","breadcrumb":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-22-understanding-the-python-importing-process\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/andrejacobs.org\/"},{"@type":"ListItem","position":2,"name":"100 Days of Learning: Day 22 \u2013 Understanding the Python importing process"}]},{"@type":"WebSite","@id":"https:\/\/andrejacobs.org\/#website","url":"https:\/\/andrejacobs.org\/","name":"Andr\u00e9 Jacobs","description":"iOS Development, Electronics, Robotics, Artificial Intelligence, Business and Health","publisher":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/andrejacobs.org\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68","name":"Andr\u00e9 Jacobs","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/","url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg","contentUrl":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg","width":450,"height":450,"caption":"Andr\u00e9 Jacobs"},"logo":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/"},"sameAs":["https:\/\/andrejacobs.org","https:\/\/www.youtube.com\/channel\/UCzqXvnd_UJ3sAzQkQBD-IVw"],"url":"https:\/\/andrejacobs.org\/author\/andre\/"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/python-logo-master-v3-TM.png","_links":{"self":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/333"}],"collection":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/comments?post=333"}],"version-history":[{"count":1,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/333\/revisions"}],"predecessor-version":[{"id":334,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/333\/revisions\/334"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/media\/254"}],"wp:attachment":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/media?parent=333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/categories?post=333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/tags?post=333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}