📦 Working with Modules and Packages
Modules and packages help you organize Python code into reusable components. They let you split large programs into smaller files, share code between projects, and use code written by others.
# Importing built-in modules
import math
import random
from datetime import datetime, timedelta
# Using imported modules
radius = 5
area = math.pi * radius ** 2
random_number = random.randint(1, 100)
current_time = datetime.now()
tomorrow = current_time + timedelta(days=1)
print(f"Circle area: {area:.2f}")
print(f"Random number: {random_number}")
print(f"Tomorrow: {tomorrow.strftime('%Y-%m-%d')}")
🎯 Understanding Modules and Packages
Modules are single Python files, while packages are directories containing multiple modules.
Basic Import Examples
# Different ways to import
import os
import json as js
from pathlib import Path
from collections import Counter, defaultdict
# Using imported items
current_dir = os.getcwd()
data = js.dumps({"name": "Alice", "age": 30})
file_path = Path("example.txt")
word_count = Counter(['apple', 'banana', 'apple'])
print(f"Current directory: {current_dir}")
print(f"JSON data: {data}")
print(f"File exists: {file_path.exists()}")
print(f"Word counts: {word_count}")
Creating Your Own Module
# Example of what you'd put in a file called 'my_utils.py'
"""
# Content of my_utils.py
def greet(name, style="casual"):
if style == "formal":
return f"Good day, {name}."
else:
return f"Hey {name}!"
def calculate_tax(amount, rate=0.08):
return amount * rate
def format_currency(amount, currency="USD"):
return f"{amount:.2f} {currency}"
# Module-level variable
DEFAULT_TAX_RATE = 0.08
"""
# How to use your custom module
# import my_utils
# message = my_utils.greet("Alice", "formal")
# tax = my_utils.calculate_tax(100, my_utils.DEFAULT_TAX_RATE)
# formatted = my_utils.format_currency(108.0)
# For demonstration, we'll simulate the module
class MyUtils:
DEFAULT_TAX_RATE = 0.08
@staticmethod
def greet(name, style="casual"):
if style == "formal":
return f"Good day, {name}."
else:
return f"Hey {name}!"
@staticmethod
def calculate_tax(amount, rate=0.08):
return amount * rate
@staticmethod
def format_currency(amount, currency="USD"):
return f"{amount:.2f} {currency}"
my_utils = MyUtils()
message = my_utils.greet("Alice", "formal")
tax = my_utils.calculate_tax(100, my_utils.DEFAULT_TAX_RATE)
formatted = my_utils.format_currency(108.0)
print(f"Message: {message}")
print(f"Tax: {tax}")
print(f"Formatted: {formatted}")
📋 Import Methods Reference
Method | Syntax | Use Case |
---|---|---|
Full import | import module | Access as module.item |
Specific import | from module import item | Use item directly |
Multiple imports | from module import a, b, c | Import several items |
Alias import | import module as alias | Shorter or clearer names |
All imports | from module import * | Import everything (avoid) |
🔧 Common Built-in Modules
Working with Files and Paths
import os
from pathlib import Path
# Using os module
current_directory = os.getcwd()
files_in_dir = os.listdir('.')
home_directory = os.path.expanduser('~')
print(f"Current dir: {current_directory}")
print(f"Files: {files_in_dir[:3]}") # Show first 3 files
# Using pathlib (modern approach)
current_path = Path.cwd()
home_path = Path.home()
# Create path objects
config_file = current_path / "config.txt"
data_dir = current_path / "data"
print(f"Config file path: {config_file}")
print(f"Data directory: {data_dir}")
print(f"Config exists: {config_file.exists()}")
Date and Time Operations
from datetime import datetime, date, timedelta
import time
# Current date and time
now = datetime.now()
today = date.today()
# Time calculations
next_week = now + timedelta(weeks=1)
yesterday = today - timedelta(days=1)
# Formatting dates
formatted_date = now.strftime("%Y-%m-%d %H:%M")
iso_date = now.isoformat()
print(f"Now: {formatted_date}")
print(f"Next week: {next_week.date()}")
print(f"Yesterday: {yesterday}")
# Working with timestamps
timestamp = time.time()
readable_time = time.ctime(timestamp)
print(f"Timestamp: {timestamp}")
print(f"Readable: {readable_time}")
JSON and Data Processing
import json
from collections import Counter, defaultdict
# Working with JSON
data = {
"users": [
{"name": "Alice", "age": 30, "city": "Boston"},
{"name": "Bob", "age": 25, "city": "New York"},
{"name": "Charlie", "age": 35, "city": "Boston"}
]
}
# Convert to JSON string
json_string = json.dumps(data, indent=2)
print("JSON string:")
print(json_string[:100] + "...")
# Parse JSON string back to Python
parsed_data = json.loads(json_string)
print(f"First user: {parsed_data['users'][0]['name']}")
# Using collections
ages = [user['age'] for user in data['users']]
cities = [user['city'] for user in data['users']]
age_counter = Counter(ages)
city_groups = defaultdict(list)
for user in data['users']:
city_groups[user['city']].append(user['name'])
print(f"Age distribution: {dict(age_counter)}")
print(f"City groups: {dict(city_groups)}")
📊 Package Structure Example
my_project/
├── main.py
├── utils/
│ ├── __init__.py
│ ├── helpers.py
│ └── validators.py
├── data/
│ ├── __init__.py
│ └── processors.py
└── tests/
├── __init__.py
└── test_utils.py
Creating Package Structure
# Example package structure (simulated)
# utils/__init__.py content:
"""
from .helpers import format_name, clean_text
from .validators import is_email_valid, is_phone_valid
"""
# utils/helpers.py content:
def format_name(first, last):
return f"{first.title()} {last.title()}"
def clean_text(text):
return text.strip().lower()
# utils/validators.py content:
import re
def is_email_valid(email):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
def is_phone_valid(phone):
# Simple phone validation
digits = re.sub(r'\D', '', phone)
return len(digits) == 10
# Simulating package usage
# from utils import format_name, is_email_valid
# For demonstration purposes:
def format_name(first, last):
return f"{first.title()} {last.title()}"
def is_email_valid(email):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
# Using the package functions
name = format_name("alice", "johnson")
valid_email = is_email_valid("alice@example.com")
invalid_email = is_email_valid("not-an-email")
print(f"Formatted name: {name}")
print(f"Valid email: {valid_email}")
print(f"Invalid email: {invalid_email}")
Module Search Path
import sys
# Python module search path
print("Python searches for modules in these locations:")
for i, path in enumerate(sys.path[:5], 1):
print(f"{i}. {path}")
# Module information
import math
print(f"\nMath module location: {math.__file__}")
print(f"Math module name: {math.__name__}")
# Check if module is available
try:
import requests
print("Requests module is available")
except ImportError:
print("Requests module is not installed")
Conditional Imports
# Conditional imports for optional dependencies
def load_json_safely(text):
try:
import json
return json.loads(text)
except ImportError:
print("JSON module not available")
return None
def enhanced_processing():
try:
from collections import Counter
data = ['a', 'b', 'a', 'c', 'b', 'a']
return Counter(data)
except ImportError:
# Fallback implementation
counts = {}
for item in ['a', 'b', 'a', 'c', 'b', 'a']:
counts[item] = counts.get(item, 0) + 1
return counts
# Test conditional imports
json_data = load_json_safely('{"name": "Alice"}')
counts = enhanced_processing()
print(f"JSON data: {json_data}")
print(f"Counts: {counts}")
🎯 Key Takeaways
🚀 What's Next?
Learn how to create virtual environments to manage project dependencies and avoid conflicts.
Continue to: Create Virtual Environments
Was this helpful?
Track Your Learning Progress
Sign in to bookmark tutorials and keep track of your learning journey.
Your progress is saved automatically as you read.