文章
学习
从 Python 到 Data/AI 一年计划计划第 4 / 10 篇 对应成果

Week 2 学习计划|Python 函数、作用域、闭包与模块化

Week 2 学习计划:函数、作用域、闭包与模块化,从参数组合、闭包、decorator 简化版到自定义 module,并把 Week 1 项目重构为 core/storage/cli/config 并加入 dataclass、type hints、logging。

PythonWeek2函数闭包decorator模块重构dataclass类型标注logging

本周计划对应一年学习计划总纲 Phase I 的 Week 2 · 函数、作用域、闭包与模块化,按总纲 Part II「每周固定执行模板」编排。计划篇只保留任务与要求,实际产出见 Week 2 学习成果。

🎯 本周目标

L1

  • 能理解并使用 function / parameter / default argument / *args / **kwargs / scope / closure / lambda / import / module / package。

L2

  • 手写参数组合、闭包、decorator 简化版、自定义 module;并把 Week 1 项目重构为 core/ / storage/ / cli/ / config/,加入 dataclass、type hints、logging。

L3

  • (总纲本周等级为 L2,不设 L3)

📚 Core Knowledge

总纲 Week 2 学习内容:

function / parameter / default argument / *args / **kwargs / scope / closure / lambda / import / module / package。

✍️ Human Core

总纲 Week 2 要求手写:

  • 参数组合
  • 闭包
  • decorator 简化版
  • 自定义 module

按日拆解如下(每天 1.5–2h:学习 45min → 实验 45min → 验收 15min)。

Day 1|函数进阶:参数、作用域、闭包(1.5–2h)

学习 45min:阅读 More on Defining Functions 与 Scopes and Namespaces,掌握 positional / keyword / default 参数、*args / **kwargs、可变默认参数陷阱、LEGB、global / nonlocal、闭包、函数是一等对象、lambda。

实验 45min:创建 function_demo.py:

  1. 参数组合:positional / keyword / default 三种传参方式
  2. 可变默认参数陷阱:
def append_to(item, target=[]):
    target.append(item)
    return target

print(append_to(1))
print(append_to(2))
print(append_to(3, []))

写出三次输出并解释原因,再用 target=None 修复。

  1. 闭包计数器 make_counter():得到 1、2、3,并验证两个计数器相互独立
  2. decorator 简化版:写一个简易装饰器,包住一个函数,在调用前后打印日志,理解“函数作为参数传入、返回新函数”与闭包的关系
  3. lambda:构造 (name, age, score) 数据,用 lambda 多字段排序

验收 15min:不用资料解释默认参数何时求值、为什么 list 默认值危险、*args 和 **kwargs 有什么区别、闭包捕获的是值还是变量、“函数是对象”意味着哪三件事。

Day 2|自定义 module 与包(1.5–2h)

学习 45min:阅读 Modules 与 Packages,掌握 module / package / subpackage、三种 import、__name__ == "__main__"、re-export、sys.path / sys.modules、循环导入。

实验 45min:创建包结构:

mypkg/
├── __init__.py
├── core.py
└── utils/
    ├── __init__.py
    └── text.py
  1. 三种 import:import mypkg.core、from mypkg import core、from mypkg.core import xxx
  2. 自定义 module:在 mypkg/core.py 中编写自己的函数模块,并用 re-export 让 from mypkg import xxx 可直接使用
  3. 模块运行方式:python core.py 与 python -m mypkg.core 观察 __name__ 差异
  4. 循环导入:人为制造 a.py → import b、b.py → import a,观察错误并修复

验收 15min:回答 import 同一模块两次代码执行几次及为什么、python file.py 和 python -m pkg.mod 的区别、循环导入为什么发生、最常见解决思路。

Day 3|闭包与作用域深化(1.5–2h)

学习 45min:深入 LEGB、闭包捕获规则、global / nonlocal 的边界,重点吃透总纲那条验收:

x = outer()
x()

为什么 x() 还能访问 outer() 中定义的变量。

实验 45min:

def outer():
    n = 0
    def inner():
        nonlocal n
        n += 1
        return n
    return inner

x = outer()
print(x())   # 1
print(x())   # 2

解释闭包如何“记住”定义时的环境,以及 nonlocal 在其中起什么作用。

验收 20min:不用资料解释为什么 x() 还能访问 outer() 里的变量。

Day 4|decorator 简化版(1.5–2h)

学习 45min:理解 decorator 本质是“接受函数、返回新函数”的高阶函数,依赖闭包保存原函数。

实验 45min:

def log(func):
    def wrapper(*args, **kwargs):
        print(f"call {func.__name__} args={args} kwargs={kwargs}")
        return func(*args, **kwargs)
    return wrapper

@log
def add(a, b):
    return a + b

验证装饰后 add(1, 2) 会先打印日志再返回 3。理解 @log 等价于 add = log(add)。

验收 15min:解释 @log 做了什么事、为什么需要 *args / **kwargs、装饰器与闭包的关系。

Day 5|L2 重构(一):目录拆分 + logging(1.5–2h)

学习 45min:阅读 logging 文档与 Logging HOWTO,掌握 Logger、Handler、Formatter、日志级别、logging.getLogger(__name__)、basicConfig;学习分层思想 storage → core → cli 与 config。

实验 45min:

  1. 目录拆分:把 Week 1 项目重构为:
project/
├── app/
│   ├── __init__.py
│   ├── core/
│   ├── storage/
│   ├── cli.py
│   └── config.py
├── tests/
└── config.json
  1. 配置与代码分离:创建 config.json,用 dataclass AppConfig 实现 load_config()
  2. logging:用 logging.getLogger(__name__) 替换 print,统一格式(时间、模块、级别、消息)
  3. 测试:保持原有测试可运行

重点实验(basicConfig):分别在 storage、cli 调用 logging.basicConfig(...),总结 basicConfig() 应由入口统一配置。

验收 15min:回答四层结构分别负责什么、为什么推荐 getLogger(__name__)、哪些东西应 / 不应放配置文件、什么信号说明“拆对了”与“越拆越乱”。

Day 6|L2 重构(二):dataclass 与 type hints(1.5–2h)

学习 45min:阅读 dataclasses 与 typing 文档,掌握 @dataclass、field、default_factory、frozen=True,以及变量 / 参数 / 返回值标注、Optional、Union、list[T]、dict[K, V]。

实验 45min:

  1. 为重构后的项目定义 dataclass 数据模型(如 AppConfig、Record),可变字段用 default_factory
  2. type hints:给 storage、core 的公开函数补全参数与返回值类型标注
  3. 运行 mypy 检查类型标注(作为重构的验证手段)

验收 15min:回答 @dataclass 自动生成哪些方法、list[str] 为什么不能直接作默认值及正确写法、Optional[int] 什么意思、类型标注会不会自动阻止错误运行。

Day 7|重构验收(1.5–2h)

Part 1|重构验收 60min:确认重构后的 Week 1 项目:目录已拆为 core/ / storage/ / cli/ / config/,dataclass、type hints、logging 均已接入,原测试全部通过。

Part 2|周复盘 45min:回答总纲验收——x = outer(); x() 为什么还能访问 outer() 中定义的变量;并记录本周手写的参数组合、闭包、decorator 简化版、自定义 module 各自产出在哪个文件。

🤖 AI Build

总纲 Week 2 要求:将 Week 1 重构为 core/、storage/、cli/、config/,并加入 dataclass、type hints、logging。

  • 目录重构为 core/ / storage/ / cli/ / config/
  • 加入 dataclass
  • 加入 type hints
  • 加入 logging

🧪 Experiment

Hypothesis

  • 通过目录拆分、dataclass、type hints 与 logging,Week 1 项目能在不改变对外行为的前提下变得可维护、可测试。

Experiment

  • 将 Week 1 的 KV 项目按职责拆为 storage / core / cli / config 四层,接入 logging 与 config.json,补充 dataclass 与类型标注,并用 pytest 验证行为不变。

Result

Conclusion

  • 重构在不改变行为的前提下提升了可维护性;basicConfig 只在入口调一次。

📝 数智工程师考试映射

  • Python 函数、作用域、闭包与 decorator
  • Python 模块与包机制(import、sys.path、sys.modules)
  • 代码组织、分层与工程化重构

✅ Acceptance

总纲 Week 2 验收:

L1

  • 能独立解释:
x = outer()
x()

为什么还能访问 outer() 中定义的变量。

L2

  • 手写参数组合、闭包、decorator 简化版、自定义 module
  • 将 Week 1 项目重构为 core/ / storage/ / cli/ / config/,加入 dataclass、type hints、logging

L3

  • 总纲本周不设 L3

🧠 本周最重要的问题

为什么 x = outer(); x() 还能访问 outer() 中定义的变量?

❓ 尚未解决

  • 待收尾:Week 1 项目重构后的 dataclass / type hints / logging 完整落地与测试
  • decorator 简化版已列入本周手写项,需确认产出文件

📊 Final Level

L2

Week 2 最终项目结构

project/
├── app/
│   ├── __init__.py
│   ├── core/
│   │   └── ...
│   ├── storage/
│   │   └── ...
│   ├── cli.py
│   └── config.py
├── tests/
│   └── ...
├── config.json
└── ...

本周产出清单

  • function_demo.py(参数组合、闭包、decorator 简化版、lambda)
  • mypkg/(自定义 module 与包)
  • Week 1 项目完成目录拆分
  • logging 接入
  • 配置文件接入
  • dataclass 与 type hints
  • mypy 检查通过

来源与延伸阅读

  1. 01Week 1 学习计划|Python 对象模型与数据结构week-1计划
  2. 02一年学习计划:从 Python 到 Data/AI 系统的 52 周计划
  3. 03Week 1 学习成果|复杂度实测、对象模型与数据结构实战week-1成果
  4. 04Week 2 学习计划|Python 函数、作用域、闭包与模块化week-2计划
  5. 05Week 2 学习成果|闭包、decorator 与工程化重构week-2成果
  6. 06Week 3 学习计划|异常、测试与 Debuggingweek-3计划
  7. 07Week 3 学习成果|异常、traceback 与 Debug 起步week-3成果
  8. 08Week 4 学习成果|Big-O 与四类基础算法week-4成果
  9. 09Week 5 学习成果|Stack、Queue 与 MinHeapweek-5成果
  10. 10Week 6 学习成果|图算法与 Python Engineering Toolkitweek-6成果