Modules & Packages
Package Architecture & Namespace Organization
Section titled “Package Architecture & Namespace Organization”- Concept: As applications scale, placing all modules (
.pyfiles) into a single directory creates namespace collisions and structural chaos. Packages solve this by mapping Python’s module namespace directly to your Operating System’s hierarchical folder structure. - The Gatekeeper (
__init__.py): A directory is just a folder to the OS. To force the Python interpreter to treat a directory as an importable package, it must contain an__init__.pyfile (which can be completely empty). - Methods & Syntax:
- Use dot notation (
.) to traverse the directory path. from package import modulefrom package.module import Class/Functionfrom package.subpackage.module import Class/Function
- Use dot notation (
Program & Architecture Implementation:
Step 1: The OS Directory Tree
└── animals/ # Top-level package ├── __init__.py # Initializes 'animals' as a package ├── crocodile.py # Module ├── monkey.py # Module └── handlers/ # Sub-package ├── __init__.py # Initializes 'handlers' as a sub-package ├── walk.py # Module └── swim.py # Module
Step 2: The Import Execution (e.g., inside your main.py)
# 1. Import a full module from the top-level packagefrom animals import crocodile
# 2. Import a specific class directly from a modulefrom animals.monkey import Monkey
# 3. Import a full module from a sub-packagefrom animals.handlers import swim
# 4. Import a specific function from a sub-package modulefrom animals.handlers.walk import is_walking
# Execution logic (assuming these definitions exist in the target files)crocodile.execute_roll()m = Monkey()swim.calculate_velocity()is_walking()`The Module & Import System
Section titled “The Module & Import System”- Concept: A module is simply a
.pyfile containing Python definitions (functions, classes, variables). You use import statements to link these files together. - Methods & Syntax:
import sys_monitor: Imports the entire file. You must prefix calls with the module name (e.g.,sys_monitor.check_cpu()).from sys_monitor import check_cpu: Extracts a specific function directly into your current namespace. No prefix needed.from sys_monitor import *: Imports everything. (Generally bad practice as it pollutes your namespace and causes naming collisions).import sys_monitor as sm: Creates an alias for the module to save typing.
Program:
# --- File: sys_monitor.py ---def check_cpu(): print("CPU load is 45%")
def check_ram(): print("RAM usage is 2GB")
# --- File: main.py ---import sys_monitor as smfrom sys_monitor import check_ram
sm.check_cpu() # Using the aliascheck_ram() # Using the direct importExecution Context (if __name__ == "__main__":)
Section titled “Execution Context (if __name__ == "__main__":)”- Concept: Python assigns a hidden global variable called
__name__to every module. The value of this variable changes depending on how the file is executed. - The Logic:
- If you run the script directly from the terminal (
python script.py), Python sets__name__ = "__main__". - If the script is imported by another file (
import script), Python sets__name__ = "script".
- If you run the script directly from the terminal (
- Purpose: It prevents background code (like CLI parsers or tests) from accidentally executing when you only wanted to import the functions.
Program:
# --- File: network_tool.py ---def ping_server(ip): print(f"Pinging {ip}...")
# This block acts as a logical gatekeeperif __name__ == "__main__": # This ONLY runs if you type 'python network_tool.py' in the Linux terminal print("Executing as a standalone script.") ping_server("192.168.1.1")else: # This runs if another script says 'import network_tool' print("Imported as a module.")The Module Search Path (sys.path)
Section titled “The Module Search Path (sys.path)”- Concept: When you type
import math, Python does not scan your entire hard drive. It searches a strict, ordered list of directories. - The Search Order:
- The exact directory where the current script is running.
- Directories listed in your OS’s
PYTHONPATHenvironment variable. - The system-default installation directories (where standard libraries and
pippackages live).
- Methods:
sys.path: A mutable list containing all the paths Python will search. You can dynamically append to it if your modules live in non-standard folders.
Program:
import sys
# Print the directories Python is currently searchingfor path in sys.path: print(path)
# Dynamically add a custom directory to the search pathsys.path.append('/home/user/custom_scripts')
# Now Python can successfully import modules located in that custom folder# import my_custom_linux_scriptModule Introspection (dir())
Section titled “Module Introspection (dir())”- Concept: A built-in function used to peek inside the memory and list all available names (variables, functions, classes) within a specific scope or module.
- Methods:
dir(): Without arguments, lists everything in the current local scope.dir(module_name): Lists all validW attributes inside that specific imported module.
Program:
import math
# Inspecting the built-in math modulemath_contents = dir(math)
print(math_contents)# Output: ['__doc__', '__name__', 'acos', 'asin', 'ceil', 'cos', 'pi', 'sqrt', ...]
# Prove it works by calling an exposed attributeif 'pi' in math_contents: print(math.pi) # Output: 3.141592653589793