Modules
A module is just a file of Python code. greet.py is the module greet: its name is the file name without .py. Other programs can use its code with import instead of copying it.
Line 1, import greet, sends Python looking for greet.py. It tries each folder on a list called sys.path: first the folder of the script you ran, then the standard library, then installed packages.
The first import runs greet.py from top to bottom. Its print() shows greet loaded and its def creates the function hello. What the file defines is kept in a module object.
Python saves the new module in sys.modules, a dictionary of every module loaded so far. Then import binds the name greet in main.py to it, so greet now means that module.
greet.hello("Ana") looks up hello inside the module greet, then calls it: Hello, Ana. Each module keeps its own names, so a hello in another file cannot clash with this one.
Line 3 imports greet again. Python finds it in sys.modules and hands back the same module object. Its code does not run a second time, so greet loaded is not printed twice.
Packages
A package is a folder of modules. The folder shapes/ holds __init__.py, which marks it as a regular package, and square.py. Inside the package, square's full name is shapes.square.
from shapes import square imports the package first, running its __init__.py, then its module shapes.square. Both are saved in sys.modules, but only the name square is added to main.py.
print(square.area(3)) calls area inside square.py, which returns 3 * 3, so 9 is printed. That was the last line of main.py, so the program ends.
Names and errors
Every module has a name in __name__. Imported, greet.py's is 'greet'; the file you run gets '__main__'. So code under if __name__ == "__main__": runs only when its file is run directly.
Misspell line 1 as import gret and the search finds no gret.py anywhere on sys.path. Python raises ModuleNotFoundError, a kind of ImportError, and the program stops unless try/except catches it.
Try it yourself
;; step 1/11
# greet.py
print("greet loaded")
def hello(name):
print("Hello,", name)
# any .py file is a module; its name is the
# file name without .py: greet
sys.path starts with the folder of the script you ran (or the current folder at the >>> prompt), then any folders listed in the PYTHONPATH environment variable, then the standard library and site-packages, where pip installs packages. sys.modules also holds many modules Python loads for itself at start-up (sys, builtins and others); the figure shows only the ones main.py adds.