{"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 A A Importing is the process by which Python code in one An Let us build up our understanding of how this importing process works by first starting with just a single 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 Let’s see what happens when we tell the interpreter to load our module.<\/p>\n Ok so we can see that when the python interpreter loaded the module it set the We then have an Add another file named module1.py inside the same directory.<\/p>\n Load and run this new module.<\/p>\n Modify example.py to import module1 and load example.py.<\/p>\n Notice how the value of Also take notice that in this case the Key point:<\/strong> The name of the module first loaded and executed by the Python interpreter will be set to Create a new directory named package1 and add a file named Modify example.py<\/p>\n Modify module1.py<\/p>\n Load and run example.py<\/p>\n Notice how the package name of example.py is example.py imported package1 and the loading system found the file named What happens if we used Can you spot the difference?<\/p>\nWhat are modules and packages?<\/h2>\n
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
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
module<\/code> is made available to Python code in another
module<\/code>.<\/p>\n
importer<\/code> is an object that does both finding and loading of modules.<\/p>\n
Single module example<\/h2>\n
module<\/code>.<\/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
$ 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
__name__<\/code> variable to
__main__<\/code>. It first ran all the code at the global scope.<\/p>\n
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
# 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
$ python module1.py\nThis is global scope of module1.py. __name__ is: __main__\nThis is module1.py running\n<\/code><\/pre>\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
__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
if __name__ ...<\/code> code from module1 was not run (as you would expect).<\/p>\n
__main__<\/code> regardless of what the module’s actual name is.<\/p>\n
Single package example<\/h2>\n
__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
...\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
...\nprint(f'This is global scope of module1.py. __name__ is: {__name__}')\nprint(f'module1.py __package__ is: {__package__}')\n...\n<\/code><\/pre>\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
None<\/code> whereas the package name for module1.py is blank (I am guessing this is an empty string ”).<\/p>\n
__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
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