Each file is a module, and modules import other modules to use the names they define. Modules are process using the following
1. import: fetch a module as a whole. It serves two purposes: it identifies the external file to be loaded, but it also becomes
a variable assigned to the loaded module.
2. from: fetch particular names from a module
3. reload: reload a module's code without stopping Python
All names defined at the top level of a module file become attributes of the imported module object. Modules have the following roles:
1. Code reuse
2. System namespace partitioning: you can never see a name in another file, unless you explicitly import that file. Like the local
scopes of functions, this helps avoid name clashes across your programs.
3. Implementing shared services and data
A Python program typically consists of text files containing Pythong statements, with one main top-level file, and zero or more
supplemental files known as modules. The top level file contains the main flow of control of your pgoram -- this is the file you run
to launch your application. The module files are libraries of tools used to collect components used by the top-level file, and possibly
elsewhere. Top level files use tools defined in module files, and modules use tools defined in other modules.
Although they are files of code too, module files generally don’t do anything when run
directly; rather, they define tools intended for use in other files. A file imports a module
to gain access to the tools it defines, which are known as its attributes—variable names
attached to objects such as functions. Ultimately, we import modules and access their
attributes to use their tools.