欢迎光临
我们一直在努力

Python 阶段实战专项练习:6 道编程题从入门到精通

配套专栏:Python 全栈修炼之路 第 12 篇《阶段实战——命令行工具开发》

难度分布:⭐ → ⭐⭐ → ⭐⭐ → ⭐⭐⭐ → ⭐⭐⭐ → ⭐⭐⭐⭐

核心覆盖:argparse、@dataclass、JSON 持久化、rich 美化输出、模块化设计、单元测试


前言

第十二篇综合运用了 Python 基础阶段的所有知识:数据类型、函数、文件操作、异常处理、模块组织、面向对象等。本练习从零开始,通过 6 个由易到难的项目,帮助你掌握从简单列表管理到完整 CLI 工具开发的全部技能。


题目一:文本版任务管理器 ⭐

📌 题目描述

用纯 Python 实现一个最简单的任务管理器,数据保存在内存中(列表),支持增删查改:

tm = TaskManager()

tm.add(\”完成Python项目\”, priority=\”high\”)
tm.add(\”阅读技术文档\”, priority=\”medium\”)
tm.add(\”回复邮件\”, priority=\”low\”)

tm.list()
# 输出:
# 1. [高] 完成Python项目
# 2. [中] 阅读技术文档
# 3. [低] 回复邮件

tm.done(1)
tm.list()
# 1. [中] 阅读技术文档
# 2. [低] 回复邮件
# 3. [高✓] 完成Python项目

tm.delete(2)
tm.list()
# 1. [低] 回复邮件
# 2. [高✓] 完成Python项目

💡 编程思路

这道题考察 基础数据结构(列表/字典)+ 函数封装 + 类设计:

  • 任务用字典表示:{\”title\”: …, \”priority\”: …, \”done\”: False}。
  • 任务列表:self.tasks = [],通过 enumerate() 生成序号。
  • 优先级映射:使用字典 {\”high\”: \”高\”, …} 实现中文显示。
  • done/delete:找到任务后修改状态或从列表移除。
  • 🖥️ 参考代码

    from typing import Optional

    class TaskManager:
    \”\”\”纯内存版任务管理器。\”\”\”

    PRIORITY_MAP = {


    \”high\”: \”高\”,
    \”medium\”: \”中\”,
    \”low\”: \”低\”,
    }

    def __init__(self):
    self.tasks: list[dict] = []

    def add(self, title: str, priority: str = \”medium\”) > None:
    \”\”\”添加任务。\”\”\”
    if priority not in self.PRIORITY_MAP:
    raise ValueError(f\”无效优先级:{

    priority},可选值: {

    list(self.PRIORITY_MAP.keys())}\”)

    task = {


    \”title\”: title,
    \”priority\”: priority,
    \”done\”: False,
    }
    self.tasks.append(task)
    print(f\”✓ 添加任务:{

    title}\”)

    def done(self, index: int) > None:
    \”\”\”标记任务完成(index 从 1 开始)。\”\”\”
    if not 1 <= index <= len(self.tasks):
    raise IndexError(f\”任务编号 {

    index} 不存在\”)
    self.tasks[index 1][\”done\”] = True
    print(f\”✓ 完成任务:{

    self.tasks[index 1][\’title\’]}\”)

    def delete(self, index: int) > None:
    \”\”\”删除任务(index 从 1 开始)。\”\”\”
    if not 1 <= index <= len(self.tasks):
    raise IndexError(f\”任务编号 {

    index} 不存在\”)
    removed = self.tasks.pop(index 1)
    print(f\”✓ 删除任务:{

    removed[\’title\’]}\”)

    def list(self) > None:
    \”\”\”列出所有任务。\”\”\”
    if not self.tasks:
    print(\”暂无任务\”)
    return

    for i, task in enumerate(self.tasks, 1):
    status = \”✓\” if task[\”done\”] else \”\”
    priority_label = self.PRIORITY_MAP[task[\”priority\”]]
    priority_str = f\”[{

    priority_label}{

    status}]\”
    print(f\”{

    i}. {

    priority_str} {

    task[\’title\’]}\”)

    def find(self, keyword: str) > list[tuple[int, dict]]:
    \”\”\”搜索包含关键词的任务。\”\”\”
    results = []
    for i, task in enumerate(self.tasks, 1):
    if keyword.lower() in task[\”title\”].lower():
    results.append((i, task))
    return results

    # 测试
    if __name__ == \”__main__\”:
    tm = TaskManager()

    print(\”=== 添加任务 ===\”)
    tm.add(\”完成Python项目\”, priority=\”high\”)
    tm.add(\”阅读技术文档\”, priority=\”medium\”)
    tm.add(\”回复邮件\”, priority=\”low\”)

    print(\”\\n=== 任务列表 ===\”)
    tm.list()

    print(\”\\n=== 搜索 ===\”)
    for idx, task in tm.find(\”文档\”):
    print(f\” #{

    idx}: {

    task[\’title\’]}\”)

    print(\”\\n=== 完成任务 ===\”)
    tm.done(1)
    tm.list()

    print(\”\\n=== 删除任务 ===\”)
    tm.delete(2)
    tm.list()

    print(\”\\n所有测试通过 ✓\”)

    🔗 关联知识点

    知识点
    说明
    list.append() 添加任务到列表
    list.pop() 删除指定位置元素
    enumerate(…, 1) 带序号的遍历
    字典映射 优先级中英文转换
    函数封装 类方法设计

    题目二:命令行版任务管理器(argparse) ⭐⭐

    📌 题目描述

    使用 argparse 将任务管理器改造为真正的命令行工具:

    $ python task_cli.py add \”完成项目文档\” –priority high
    ✓ 任务已添加

    $ python task_cli.py list
    1. [] 完成项目文档

    $ python task_cli.py done 1
    ✓ 任务已完成

    $ python task_cli.py delete 1 –force
    ✓ 任务已删除

    $ python task_cli.py –help
    usage: task_cli.py [-h] {

    add,list,done,delete} ...

    任务管理器 CLI
    ...

    💡 编程思路

    这道题考察 argparse 子命令解析 + CLI 程序结构:

  • 子命令模式:使用 add_subparsers() 为每个操作创建子命令。
  • 参数定义:每个子命令定义自己的参数(add_parser + add_argument)。
  • 命令分发:通过 getattr(self, f\”cmd_{args.command}\”) 动态调用对应方法。
  • 数据存储:仍然用内存列表,但加上文件持久化(保存到 JSON)。
  • 🖥️ 参考代码

    \”\”\”命令行版任务管理器(使用 argparse)。\”\”\”

    import argparse
    import json
    import os
    from pathlib import Path
    from typing import Optional

    class TaskItem:
    \”\”\”任务数据类(用普通类模拟 dataclass)。\”\”\”

    def __init__(self, title: str, priority: str = \”medium\”, done: bool = False):
    self.title = title
    self.priority = priority
    self.done = done

    def to_dict(self) > dict:
    return {

    \”title\”: self.title, \”priority\”: self.priority, \”done\”: self.done}

    @classmethod
    def from_dict(cls, data: dict) > \”TaskItem\”:
    return cls(data[\”title\”], data.get(\”priority\”, \”medium\”), data.get(\”done\”, False))

    class TaskCLI:
    \”\”\”任务管理 CLI。\”\”\”

    DATA_FILE = Path.home() / \”.taskcli\” / \”tasks.json\”

    def __init__(self):
    self.tasks: list[TaskItem] = []
    self._ensure_data_dir()
    self._load()

    def _ensure_data_dir(self):
    self.DATA_FILE.parent.mkdir(parents=True, exist_ok=True)

    def _load(self):
    if self.DATA_FILE.exists():
    try:
    with open(self.DATA_FILE, \”r\”, encoding=\”utf-8\”) as f:
    data = json.load(f)
    self.tasks = [TaskItem.from_dict(t) for t in data]
    except (json.JSONDecodeError, KeyError):
    self.tasks = []

    def _save(self):
    with open(self.DATA_FILE, \”w\”, encoding=\”utf-8\”) as f:
    json.dump([t.to_dict() for t in self.tasks], f, ensure_ascii=False, indent=2)

    # === 命令处理方法 ===

    def cmd_add(self, args):
    task = TaskItem(title=args.title, priority=args.priority)
    self.tasks.append(task)
    self._save()
    print(f\”✓ 任务已添加(当前共 {

    len(self.tasks)} 个任务)\”)

    def cmd_list(self, args):
    if not self.tasks:
    print(\”暂无任务\”)
    return

    for i, task in enumerate(self.tasks, 1):
    mark = \”✓\” if task.done else \” \”
    priority_map = {

    \”high\”: \”高\”, \”medium\”: \”中\”, \”low\”: \”低\”}
    pri = priority_map[task.priority]
    status = f\”[{

    pri}]\” if not task.done else f\”[{

    pri}✓]\”
    print(f\”{

    i}. {

    status} {

    task.title}\”)

    # 统计
    done_count = sum(1 for t in self.tasks if t.done)
    print(f\”\\n共 {

    len(self.tasks)} 个任务,已完成 {

    done_count} 个\”)

    def cmd_done(self, args):
    try:
    idx = int(args.index) 1
    if not 0 <= idx < len(self.tasks):
    raise IndexError
    self.tasks[idx].done = True
    self._save()
    print(f\”✓ 任务已完成:{

    self.tasks[idx].title}\”)
    except (ValueError, IndexError):
    print(f\”✗ 任务编号 {

    args.index} 不存在\”)

    def cmd_delete(self, args):
    if not args.force:
    confirm = input(f\”确认删除任务 {

    args.index}?[y/N]: \”)
    if confirm.lower() != \”y\”:
    print(\”已取消\”)
    return
    try:
    idx = int(args.index) 1
    removed = self.tasks.pop(idx)
    self._save()
    print(f\”✓ 任务已删除:{

    removed.title}\”)
    except (ValueError, IndexError):
    print(f\”✗ 任务编号 {

    args.index} 不存在\”)

    def cmd_clear(self, args):
    if not args.force:
    confirm = input(f\”确认清空所有 {

    len(self.tasks)} 个任务?[y/N]: \”)
    if confirm.lower() != \”y\”:
    print(\”已取消\”)
    return
    self.tasks.clear()
    self._save()
    print(\”✓ 所有任务已清空\”)

    def run(self, args=None):
    \”\”\”运行 CLI。\”\”\”
    parser = self._create_parser()
    parsed = parser.parse_args(args)

    if not parsed.command:
    parser.print_help()
    return

    cmd_method = getattr(self, f\”cmd_{

    parsed.command}\”, None)
    if cmd_method:
    cmd_method(parsed)
    else:
    print(f\”✗ 未知命令:{

    parsed.command}\”)

    def _create_parser(self) > argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
    prog=\”taskcli\”,
    description=\”任务管理器 CLI\”,
    formatter_class=argparse.RawDescriptionHelpFormatter,
    )

    sub = parser.add_subparsers(dest=\”command\”, help=\”可用命令\”)

    # add
    p_add = sub.add_parser(\”add\”, help=\”添加新任务\”)
    p_add.add_argument(\”title\”, help=\”任务标题\”)
    p_add.add_argument(\”-p\”, \”–priority\”, choices=[\”high\”, \”medium\”, \”low\”],
    default=\”medium\”, help=\”优先级(默认 medium)\”)

    # list
    sub.add_parser(\”list\”, help=\”列出所有任务\”)

    # done
    p_done = sub.add_parser(\”done\”, help=\”标记任务完成\”)
    p_done.add_argument(\”index\”, help=\”任务编号\”)

    # delete
    p_del = sub.add_parser(\”delete\”, help=\”删除任务\”)
    p_del.add_argument(\”index\”, help=\”任务编号\”)
    p_del.add_argument(\”-f\”, \”–force\”, action=\”store_true\”, help=\”跳过确认\”)

    # clear
    p_clear = sub.add_parser(\”clear\”, help=\”清空所有任务\”)
    p_clear.add_argument(\”-f\”, \”–force\”, action=\”store_true\”, help=\”跳过确认\”)

    return parser

    def main():
    cli = TaskCLI()
    cli.run()

    if __name__ == \”__main__\”:
    main()

    🔗 关联知识点

    知识点
    说明
    argparse.ArgumentParser 命令行参数解析器
    add_subparsers() 子命令模式
    add_argument() 定义参数(位置/可选)
    getattr(dynamic) 动态方法调用
    JSON 文件持久化 _save() / _load()

    题目三:任务模型(dataclass + Enum + TypeHint) ⭐⭐

    📌 题目描述

    使用 @dataclass、Enum 和类型提示重构任务模型:

    from datetime import date, timedelta

    # 创建任务
    task = Task(
    title=\”完成项目文档\”,
    priority=Priority.HIGH,
    due_date=date.today() + timedelta(days=7)
    )

    print(task)
    # Task: 完成项目文档 [高] 剩余7天

    # 逾期检测
    task.due_date = date.today() timedelta(days=1)
    print(task.is_overdue()) # True
    print(task) # Task: 完成项目文档 [高] 已逾期!

    # 数据序列化
    data = task.to_dict()
    print(data)
    # {\’title\’: \’完成项目文档\’, \’priority\’: \’HIGH\’, \’due_date\’: \’…\’, …}

    # 比较和哈希
    task2 = Task(title=\”完成项目文档\”, priority=Priority.HIGH)
    print(task == task2) # True(相同标题+优先级视为相等)

    💡 编程思路

    这道题考察 @dataclass + Enum + @property + 类型提示:

  • @dataclass:自动生成 __init__、__repr__、__eq__ 等方法。
  • field(default_factory=…):为列表等可变类型提供默认值。
  • @property:将 is_overdue 等方法转为只读属性。
  • Enum:用枚举类定义优先级,保证类型安全。
  • __post_init__:在初始化后进行验证。
  • 🖥️ 参考代码

    from dataclasses import dataclass, field
    from datetime import date, datetime
    from enum import Enum, auto
    from typing import Optional
    import uuid

    class Priority(Enum):
    \”\”\”任务优先级枚举。\”\”\”
    LOW = auto()
    MEDIUM = auto()
    HIGH = auto()

    @property
    def label(self) > str:
    return {

    Priority.LOW: \”低\”, Priority.MEDIUM: \”中\”, Priority.HIGH: \”高\”}[self]

    @property
    def weight(self) > int:
    \”\”\”优先级权重(数值越大越重要)。\”\”\”
    return {

    Priority.LOW: 1, Priority.MEDIUM: 2, Priority.HIGH: 3}[self]

    class Status(Enum):
    \”\”\”任务状态枚举。\”\”\”
    TODO = auto()
    IN_PROGRESS = auto()
    DONE = auto()

    @property
    def label(self) > str:
    return {

    Status.TODO: \”待办\”, Status.IN_PROGRESS: \”进行中\”, Status.DONE: \”已完成\”}[self]

    @dataclass
    class Task:
    \”\”\”任务数据类。\”\”\”

    title: str
    priority: Priority = Priority.MEDIUM
    status: Status = Status.TODO
    description: str = \”\”
    due_date: Optional[date] = None
    tags: list[str] = field(default_factory=list)

    # 自动生成字段
    id: str = field(default_factory=lambda: str(uuid.<

    赞(0)
    未经允许不得转载:171主机测评 » Python 阶段实战专项练习:6 道编程题从入门到精通
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址