Skip to content

Modules & Packages

Package Architecture & Namespace Organization

Section titled “Package Architecture & Namespace Organization”
  • Concept: As applications scale, placing all modules (.py files) 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__.py file (which can be completely empty).
  • Methods & Syntax:
    • Use dot notation (.) to traverse the directory path.
    • from package import module
    • from package.module import Class/Function
    • from package.subpackage.module import Class/Function

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 package
from animals import crocodile
# 2. Import a specific class directly from a module
from animals.monkey import Monkey
# 3. Import a full module from a sub-package
from animals.handlers import swim
# 4. Import a specific function from a sub-package module
from 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()`
  • Concept: A module is simply a .py file 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 sm
from sys_monitor import check_ram
sm.check_cpu() # Using the alias
check_ram() # Using the direct import

Execution 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".
  • 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 gatekeeper
if __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.")

  • 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:
  1. The exact directory where the current script is running.
  2. Directories listed in your OS’s PYTHONPATH environment variable.
  3. The system-default installation directories (where standard libraries and pip packages 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 searching
for path in sys.path:
print(path)
# Dynamically add a custom directory to the search path
sys.path.append('/home/user/custom_scripts')
# Now Python can successfully import modules located in that custom folder
# import my_custom_linux_script

  • 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 module
math_contents = dir(math)
print(math_contents)
# Output: ['__doc__', '__name__', 'acos', 'asin', 'ceil', 'cos', 'pi', 'sqrt', ...]
# Prove it works by calling an exposed attribute
if 'pi' in math_contents:
print(math.pi) # Output: 3.141592653589793