今日练习主题:模块、包和Python标准库
今天我们将学习Python的模块系统、包的创建和使用,以及Python标准库中一些常用模块的功能。
练习1:创建和使用自定义模块
# 先创建 math_utils.py 文件
"""
math_utils.py - 数学工具模块
提供各种数学计算函数
"""
def add(a, b):
"""返回两个数的和"""
return a + b
def subtract(a, b):
"""返回两个数的差"""
return a - b
def multiply(a, b):
"""返回两个数的积"""
return a * b
def divide(a, b):
"""返回两个数的商,处理除零错误"""
if b == 0:
raise ValueError("除数不能为零")
return a / b
def factorial(n):
"""计算阶乘"""
if n < 0:
raise ValueError("阶乘不能为负数")
result = 1
for i in range(1, n + 1):
result *= i
return result
def is_prime(n):
"""判断是否为质数"""
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
# 模块测试代码
if __name__ == "__main__":
print("测试数学工具模块:")
print(f"5 + 3 = {add(5, 3)}")
print(f"10 - 4 = {subtract(10, 4)}")
print(f"6 * 7 = {multiply(6, 7)}")
print(f"15 / 3 = {divide(15, 3)}")
print(f"5! = {factorial(5)}")
print(f"17是质数吗? {is_prime(17)}")
# 在另一个文件中使用自定义模块
# main.py
import math_utils as mu
from math_utils import is_prime
print("=== 使用自定义数学模块 ===")
# 使用模块中的函数
result = mu.add(10, 20)
print(f"10 + 20 = {result}")
result = mu.multiply(5, 6)
print(f"5 × 6 = {result}")
# 测试质数判断
numbers = [2, 3, 4, 5, 17, 21, 29]
print("
质数检测:")
for num in numbers:
print(f"{num} 是质数: {is_prime(num)}")
# 测试异常处理
try:
result = mu.divide(10, 0)
except ValueError as e:
print(f"
错误: {e}")
# 查看模块信息
print(f"
模块名称: {mu.__name__}")
print(f"模块文档: {mu.__doc__}")
练习2:创建和使用包
# 创建包结构:
# my_package/
# │
# ├── __init__.py
# ├── string_utils.py
# ├── file_utils.py
# └── data_utils.py
# __init__.py 文件内容:
"""
my_package - 实用工具包
包含字符串处理、文件操作和数据工具
"""
from .string_utils import reverse_string, count_words
from .file_utils import read_file, write_file
from .data_utils import DataProcessor
__version__ = "1.0.0"
__author__ = "Python学习者"
# string_utils.py 文件内容:
def reverse_string(s):
"""反转字符串"""
return s[::-1]
def count_words(text):
"""统计文本中的单词数"""
words = text.split()
return len(words)
def to_title_case(text):
"""转换为标题格式"""
return text.title()
# file_utils.py 文件内容:
import os
def read_file(filename):
"""读取文件内容"""
if not os.path.exists(filename):
raise FileNotFoundError(f"文件 {filename} 不存在")
with open(filename, 'r', encoding='utf-8') as file:
return file.read()
def write_file(filename, content):
"""写入文件内容"""
with open(filename, 'w', encoding='utf-8') as file:
file.write(content)
def file_exists(filename):
"""检查文件是否存在"""
return os.path.exists(filename)
# data_utils.py 文件内容:
class DataProcessor:
"""数据处理类"""
def __init__(self, data):
self.data = data
def get_stats(self):
"""获取数据统计信息"""
if not self.data:
return {}
return {
'count': len(self.data),
'sum': sum(self.data),
'average': sum(self.data) / len(self.data),
'max': max(self.data),
'min': min(self.data)
}
def filter_data(self, condition):
"""过滤数据"""
return [x for x in self.data if condition(x)]
# 使用自定义包
from my_package import reverse_string, count_words, read_file, DataProcessor
import my_package as mp
print("=== 使用自定义包 ===")
# 使用字符串工具
text = "Hello World Python Programming"
print(f"原始文本: {text}")
print(f"反转文本: {reverse_string(text)}")
print(f"单词数量: {count_words(text)}")
# 使用数据处理
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
processor = DataProcessor(data)
stats = processor.get_stats()
print(f"
数据统计: {stats}")
# 过滤数据
even_numbers = processor.filter_data(lambda x: x % 2 == 0)
print(f"偶数: {even_numbers}")
# 查看包信息
print(f"
包版本: {mp.__version__}")
print(f"作者: {mp.__author__}")
练习3:os和sys模块
import os
import sys
print("=== os 和 sys 模块使用 ===")
# os模块示例
print(f"当前工作目录: {os.getcwd()}")
print(f"操作系统: {os.name}")
print(f"环境变量PATH: {os.getenv('PATH', '未找到')}")
# 文件和目录操作
current_dir = os.getcwd()
print(f"当前目录内容: {os.listdir(current_dir)}")
# 创建测试目录和文件
test_dir = "test_dir"
if not os.path.exists(test_dir):
os.makedirs(test_dir)
print(f"创建目录: {test_dir}")
test_file = os.path.join(test_dir, "test.txt")
with open(test_file, 'w') as f:
f.write("Hello OS Module!")
print(f"文件大小: {os.path.getsize(test_file)} 字节")
print(f"是文件吗? {os.path.isfile(test_file)}")
print(f"是目录吗? {os.path.isdir(test_dir)}")
# sys模块示例
print(f"
Python版本: {sys.version}")
print(f"平台: {sys.platform}")
print(f"命令行参数: {sys.argv}")
print(f"默认编码: {sys.getdefaultencoding()}")
# 模块搜索路径
print("
模块搜索路径:")
for path in sys.path:
print(f" {path}")
# 清理
import shutil
shutil.rmtree(test_dir)
print(f"
已清理测试目录: {test_dir}")
练习4:datetime和time模块
import datetime
import time
print("=== datetime 和 time 模块使用 ===")
# datetime模块
now = datetime.datetime.now()
print(f"当前时间: {now}")
print(f"日期: {now.date()}")
print(f"时间: {now.time()}")
print(f"年份: {now.year}, 月份: {now.month}, 日: {now.day}")
# 时间计算
tomorrow = now + datetime.timedelta(days=1)
last_week = now - datetime.timedelta(weeks=1)
print(f"明天: {tomorrow}")
print(f"上周: {last_week}")
# 时间格式化
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"格式化时间: {formatted}")
# 解析时间字符串
time_str = "2024-01-15 14:30:00"
parsed_time = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S")
print(f"解析的时间: {parsed_time}")
# time模块
print(f"
当前时间戳: {time.time()}")
print(f"可读时间: {time.ctime()}")
# 计时功能
start_time = time.time()
time.sleep(2) # 休眠2秒
end_time = time.time()
print(f"程序运行时间: {end_time - start_time:.2f} 秒")
# 性能计时
start = time.perf_counter()
sum(range(1000000))
end = time.perf_counter()
print(f"计算耗时: {end - start:.6f} 秒")
练习5:random和json模块
import random
import json
print("=== random 和 json 模块使用 ===")
# random模块
print("随机数示例:")
print(f"随机整数(1-100): {random.randint(1, 100)}")
print(f"随机浮点数: {random.random():.3f}")
print(f"随机选择: {random.choice(['苹果', '香蕉', '橙子', '葡萄'])}")
# 随机抽样
numbers = list(range(1, 11))
random.shuffle(numbers)
print(f"打乱列表: {numbers}")
print(f"随机样本: {random.sample(numbers, 3)}")
# 生成随机数据
random_data = [random.randint(1, 100) for _ in range(5)]
print(f"随机数据列表: {random_data}")
# json模块
print("
JSON操作示例:")
# Python对象转换为JSON
data = {
"name": "张三",
"age": 25,
"is_student": False,
"courses": ["数学", "英语", "编程"],
"scores": {"数学": 90, "英语": 85, "编程": 95}
}
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print("JSON字符串:")
print(json_str)
# JSON转换为Python对象
parsed_data = json.loads(json_str)
print("
解析后的Python对象:")
print(f"姓名: {parsed_data['name']}")
print(f"年龄: {parsed_data['age']}")
print(f"课程: {', '.join(parsed_data['courses'])}")
# 文件读写JSON
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open('data.json', 'r', encoding='utf-8') as f:
loaded_data = json.load(f)
print(f"
从文件加载的数据: {loaded_data['name']}")
# 清理
import os
if os.path.exists('data.json'):
os.remove('data.json')
练习6:collections和itertools模块
from collections import Counter, defaultdict, deque
import itertools
print("=== collections 和 itertools 模块使用 ===")
# collections.Counter
words = ["apple", "banana", "apple", "orange", "banana", "apple"]
word_count = Counter(words)
print(f"单词计数: {word_count}")
print(f"最常见的2个: {word_count.most_common(2)}")
# collections.defaultdict
student_grades = defaultdict(list)
student_grades["张三"].append(90)
student_grades["李四"].append(85)
student_grades["张三"].append(95)
print(f"学生成绩: {dict(student_grades)}")
# collections.deque (双端队列)
queue = deque([1, 2, 3])
queue.append(4) # 右边添加
queue.appendleft(0) # 左边添加
print(f"队列: {queue}")
print(f"弹出左边: {queue.popleft()}")
print(f"弹出右边: {queue.pop()}")
# itertools
print("
itertools示例:")
# 无限迭代器
counter = itertools.count(start=10, step=2)
print(f"计数器前5个: {[next(counter) for _ in range(5)]}")
# 排列组合
letters = ['A', 'B', 'C']
print(f"排列: {list(itertools.permutations(letters, 2))}")
print(f"组合: {list(itertools.combinations(letters, 2))}")
# 链式迭代
chained = list(itertools.chain([1, 2, 3], [4, 5, 6]))
print(f"链式迭代: {chained}")
# 分组
data = [1, 1, 2, 2, 3, 3, 3]
grouped = {k: list(v) for k, v in itertools.groupby(data)}
print(f"分组: {grouped}")
练习7:re模块(正则表达式)
import re
print("=== re 模块使用(正则表达式)===")
text = """
我的电话号码是: 138-1234-5678
公司电话: 010-8888-9999
紧急联系: 120
邮箱: example@email.com
另一个邮箱: test.user@domain.cn
网址: https://www.example.com
IP地址: 192.168.1.1
日期: 2024-01-15
"""
# 匹配电话号码
phone_pattern = r'd{3}-d{4}-d{4}'
phones = re.findall(phone_pattern, text)
print(f"找到的电话号码: {phones}")
# 匹配邮箱
email_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}'
emails = re.findall(email_pattern, text)
print(f"找到的邮箱: {emails}")
# 匹配URL
url_pattern = r'https?://[a-zA-Z0-9.-]+.[a-zA-Z]{2,}'
urls = re.findall(url_pattern, text)
print(f"找到的URL: {urls}")
# 替换操作
new_text = re.sub(r'd{3}-d{4}-d{4}', '***-****-****', text)
print("
替换电话号码后的文本:")
print(new_text)
# 分割操作
sample_text = "apple,banana;orange grape"
items = re.split(r'[,; ]', sample_text)
print(f"分割结果: {items}")
# 搜索和匹配
match = re.search(r'日期: (d{4}-d{2}-d{2})', text)
if match:
print(f"找到日期: {match.group(1)}")
# 验证字符串
def is_valid_email(email):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
test_emails = ["test@example.com", "invalid.email", "user@domain"]
for email in test_emails:
print(f"{email} 是有效邮箱吗? {is_valid_email(email)}")
今日挑战:
创建一个完整的项目结构,包含多个模块和包,实现一个简单的任务管理系统。
# 项目结构:
# task_manager/
# │
# ├── __init__.py
# ├── main.py
# ├── models/
# │ ├── __init__.py
# │ ├── task.py
# │ └── user.py
# ├── utils/
# │ ├── __init__.py
# │ ├── file_utils.py
# │ └── date_utils.py
# └── data/
# └── tasks.json
# models/task.py
import json
from datetime import datetime
from enum import Enum
class Priority(Enum):
LOW = 1
MEDIUM = 2
HIGH = 3
class Status(Enum):
PENDING = "待完成"
IN_PROGRESS = "进行中"
COMPLETED = "已完成"
class Task:
def __init__(self, title, description, priority=Priority.MEDIUM, due_date=None):
self.title = title
self.description = description
self.priority = priority
self.status = Status.PENDING
self.created_at = datetime.now()
self.due_date = due_date
self.completed_at = None
def mark_completed(self):
self.status = Status.COMPLETED
self.completed_at = datetime.now()
def to_dict(self):
return {
'title': self.title,
'description': self.description,
'priority': self.priority.value,
'status': self.status.value,
'created_at': self.created_at.isoformat(),
'due_date': self.due_date.isoformat() if self.due_date else None,
'completed_at': self.completed_at.isoformat() if self.completed_at else None
}
@classmethod
def from_dict(cls, data):
task = cls(data['title'], data['description'])
task.priority = Priority(data['priority'])
task.status = Status(data['status'])
task.created_at = datetime.fromisoformat(data['created_at'])
task.due_date = datetime.fromisoformat(data['due_date']) if data['due_date'] else None
task.completed_at = datetime.fromisoformat(data['completed_at']) if data['completed_at'] else None
return task
# utils/file_utils.py
import json
import os
def save_tasks(tasks, filename='data/tasks.json'):
"""保存任务到JSON文件"""
os.makedirs(os.path.dirname(filename), exist_ok=True)
with open(filename, 'w', encoding='utf-8') as f:
json.dump([task.to_dict() for task in tasks], f, ensure_ascii=False, indent=2)
def load_tasks(filename='data/tasks.json'):
"""从JSON文件加载任务"""
if not os.path.exists(filename):
return []
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
return [Task.from_dict(task_data) for task_data in data]
# utils/date_utils.py
from datetime import datetime, timedelta
def get_current_time():
"""获取当前时间"""
return datetime.now()
def format_date(date, format_str="%Y-%m-%d %H:%M"):
"""格式化日期"""
if date:
return date.strftime(format_str)
return "未设置"
def parse_date(date_str, format_str="%Y-%m-%d"):
"""解析日期字符串"""
try:
return datetime.strptime(date_str, format_str)
except ValueError:
return None
# main.py
from models.task import Task, Priority, Status
from utils.file_utils import save_tasks, load_tasks
from utils.date_utils import format_date, parse_date
import sys
class TaskManager:
def __init__(self):
self.tasks = load_tasks()
def add_task(self, title, description, priority=Priority.MEDIUM, due_date=None):
"""添加新任务"""
task = Task(title, description, priority, due_date)
self.tasks.append(task)
save_tasks(self.tasks)
print(f"任务 '{title}' 添加成功!")
def list_tasks(self, filter_status=None):
"""列出任务"""
if not self.tasks:
print("没有任务")
return
filtered_tasks = self.tasks
if filter_status:
filtered_tasks = [t for t in self.tasks if t.status == filter_status]
print(f"
{'='*60}")
print(f"{'任务列表':^60}")
print(f"{'='*60}")
for i, task in enumerate(filtered_tasks, 1):
print(f"{i}. {task.title}")
print(f" 描述: {task.description}")
print(f" 优先级: {task.priority.name}")
print(f" 状态: {task.status.value}")
print(f" 创建时间: {format_date(task.created_at)}")
if task.due_date:
print(f" 截止时间: {format_date(task.due_date)}")
if task.completed_at:
print(f" 完成时间: {format_date(task.completed_at)}")
print(f" {'-'*40}")
def complete_task(self, task_index):
"""标记任务完成"""
if 0 <= task_index < len(self.tasks):
task = self.tasks[task_index]
if task.status != Status.COMPLETED:
task.mark_completed()
save_tasks(self.tasks)
print(f"任务 '{task.title}' 已完成!")
else:
print("任务已经是完成状态")
else:
print("无效的任务索引")
def run(self):
"""运行任务管理器"""
print("=== 任务管理系统 ===")
while True:
print("
请选择操作:")
print("1. 添加任务")
print("2. 查看所有任务")
print("3. 查看待完成任务")
print("4. 标记任务完成")
print("5. 退出")
choice = input("请输入选项 (1-5): ")
if choice == "1":
title = input("任务标题: ")
description = input("任务描述: ")
priority = input("优先级 (LOW/MEDIUM/HIGH, 默认为MEDIUM): ").upper()
due_date_str = input("截止日期 (YYYY-MM-DD, 可选): ")
priority_map = {"LOW": Priority.LOW, "MEDIUM": Priority.MEDIUM, "HIGH": Priority.HIGH}
priority = priority_map.get(priority, Priority.MEDIUM)
due_date = parse_date(due_date_str) if due_date_str else None
self.add_task(title, description, priority, due_date)
elif choice == "2":
self.list_tasks()
elif choice == "3":
self.list_tasks(Status.PENDING)
elif choice == "4":
self.list_tasks(Status.PENDING)
if any(task.status == Status.PENDING for task in self.tasks):
try:
task_num = int(input("请输入要完成的任务编号: ")) - 1
self.complete_task(task_num)
except ValueError:
print("请输入有效的数字")
elif choice == "5":
print("感谢使用任务管理系统!")
break
else:
print("无效选项,请重新选择")
if __name__ == "__main__":
manager = TaskManager()
manager.run()
学习提示:
- 模块:单个Python文件,包含可重用的代码
- 包:包含多个模块的目录,必须有 __init__.py 文件
- 标准库:Python自带的丰富模块集合
- import语句:导入模块或特定功能
- if __name__ == “__main__”:模块测试代码
- 相对导入:在包内使用 . 导入相对路径的模块
明天我们将学习错误处理和调试技巧!坚持练习,你的代码组织能力会越来越强!
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END

















- 最新
- 最热
只看作者