🤖 AI 时代的 Python 学习

成为 AI 时代的智能协作者

在 AI 编程日益成熟的背景下,Python 学习的目标已从"成为熟练的编码者"转变为"成为能与 AI 高效协作的架构师与质检员"。本课程精简语法、强化数据处理、突出面向对象思维,完全融入与 AI 协作的实践方法。

4
核心模块
15+
知识要点
25+
代码示例
01

核心语法与思维:理解 AI 生成的代码

这是与 AI 协作的基石。你无需记忆所有语法细节,但必须能读懂、调试和修改 AI 生成的代码。

1.1 基础语法与数据结构

什么是变量?

想象你有一排收纳盒,每个盒子上都贴着一张标签。标签上写着盒子里装的是什么 —— 比如"学习率"、"模型名称"、"训练轮数"。在 Python 中,变量就是标签,它指向内存中存储的数据

你不需要提前声明盒子的类型(不像 Java 或 C++),Python 会自动判断。这叫做动态类型

Python
# 变量就像给数据贴标签
model_name = "ResNet50"     # 标签 model_name 指向字符串 "ResNet50"
learning_rate = 0.001       # 标签 learning_rate 指向浮点数 0.001
num_layers = 50              # 标签 num_layers 指向整数 50
is_training = True          # 标签 is_training 指向布尔值 True

# 变量可以被重新赋值(标签贴到新的盒子上)
learning_rate = 0.0005       # 学习率从 0.001 改为 0.0005
print(learning_rate)             # 输出: 0.0005
概念解释:动态类型 vs 静态类型

Python 是动态类型语言,你写 x = 10 时不需要告诉 Python "x 是一个整数",它会自动推断。而 Java 等静态类型语言需要写 int x = 10;。动态类型让代码更简洁,这也是 AI 更喜欢生成 Python 代码的原因之一。

Python 的四种基本数据类型

Python 中有四种最常用的基本数据类型,就像生活中有不同种类的容器来装不同类型的物品。

数据类型关键字说明AI 场景示例
整数int没有小数点的数字epochs = 100(训练轮数)
浮点数float带小数点的数字lr = 0.001(学习率)
字符串str文本,用引号包裹optimizer = "adam"(优化器名称)
布尔值bool只有 True 或 Falseuse_gpu = True(是否使用GPU)
Python
# ===== 四种基本数据类型 =====

# 1. 整数 int — 用于计数、索引
batch_size = 32           # 每批训练 32 个样本
num_classes = 10          # 分类任务的类别数
print(type(batch_size))    # <class 'int'>

# 2. 浮点数 float — 用于精度、比率
learning_rate = 0.001     # 学习率,需要精确的小数
accuracy = 0.9567         # 模型准确率 95.67%
print(type(learning_rate)) # <class 'float'>

# 3. 字符串 str — 用于名称、路径、标签
model_name = "BERT"       # 模型名称
data_path = "./dataset/"  # 数据集路径
print(type(model_name))    # <class 'str'>

# 4. 布尔值 bool — 用于开关、判断
use_gpu = True             # 是否使用 GPU 加速
is_debug = False            # 是否开启调试模式
print(type(use_gpu))         # <class 'bool'>

# 类型转换(AI 代码中常见)
loss_str = "0.85"           # 从日志中读取的字符串
loss_val = float(loss_str)    # 转换为浮点数 0.85
epoch_str = "10"            # 字符串 "10"
epoch_int = int(epoch_str)     # 转换为整数 10
运算符

运算符是对数据进行操作的符号。Python 提供了三大类运算符,在 AI 代码中几乎无处不在。

类别运算符说明AI 场景示例
算术运算符+ - * / // % **数学计算total_loss = loss1 + loss2
比较运算符== != > < >= <=比较大小,返回布尔值if accuracy >= 0.9:
逻辑运算符and or not组合条件判断if loss < 0.1 and acc > 0.95:
Python
# ===== 算术运算符 =====
a, b = 10, 3
print(a + b)    # 13   加法
print(a - b)    # 7    减法
print(a * b)    # 30   乘法
print(a / b)    # 3.33 除法(结果为浮点数)
print(a // b)   # 3    整除(只保留整数部分)
print(a % b)    # 1    取余(10 除以 3 余 1)
print(a ** b)   # 1000 幂运算(10 的 3 次方)

# ===== 比较运算符 =====
accuracy = 0.92
print(accuracy == 0.92)   # True  等于
print(accuracy != 1.0)    # True  不等于
print(accuracy >= 0.9)    # True  大于等于
print(accuracy < 0.8)     # False 小于

# ===== 逻辑运算符 =====
loss = 0.08
acc = 0.96
print(loss < 0.1 and acc > 0.9)   # True  两个条件都满足
print(loss < 0.01 or acc > 0.9)    # True  至少一个满足
print(not loss < 0.01)              # True  取反
输入与输出:print() 和 input()

print() 用于将信息输出到屏幕,input() 用于从键盘获取用户输入。在 AI 开发中,print() 是调试和监控训练过程的重要工具。

Python
# ===== print() 输出 =====

# 基本输出
print("模型训练开始...")

# f-string 格式化输出(推荐!AI 代码中最常用)
epoch = 5
loss = 0.234
acc = 0.912
print(f"Epoch {epoch}: loss={loss:.4f}, acc={acc:.2%}")
# 输出: Epoch 5: loss=0.2340, acc=91.20%

# 多个变量输出
print("Loss:", loss, "Accuracy:", acc)

# ===== input() 输入 =====
model_name = input("请输入模型名称: ")
print(f"你选择的模型是: {model_name}")

# 注意:input() 返回的永远是字符串,需要手动转换
epochs_input = input("请输入训练轮数: ")
epochs = int(epochs_input)  # 转换为整数
print(f"将训练 {epochs} 轮")
学习技巧:f-string 格式化

在字符串前加 f,就可以在 {} 中直接嵌入变量。{loss:.4f} 表示保留4位小数,{acc:.2%} 表示显示为百分比并保留2位小数。这是 Python 3.6+ 的语法,AI 生成的代码几乎都使用这种格式。

列表(List)详解

列表是 Python 中最常用的数据结构之一。你可以把它想象成一个有序的收纳架,每个格子上都有编号(从0开始),你可以往里面放东西、取东西、修改东西。

概念解释:什么是列表?

列表是一个有序的、可修改的元素集合。用方括号 [] 创建。列表中的元素可以是任何类型,甚至可以是不同类型的混合。在 AI 开发中,列表常用于存储训练过程中的损失值、准确率等历史记录。

Python — 列表基础
# ===== 创建列表 =====
loss_history = [0.9, 0.7, 0.5, 0.3, 0.15]  # 存储每轮训练的损失值
model_names = ["ResNet", "BERT", "GPT"]     # 模型名称列表
empty_list = []                            # 空列表

# ===== 索引访问(从 0 开始!)=====
print(loss_history[0])    # 0.9   第一个元素
print(loss_history[-1])   # 0.15  最后一个元素(-1表示倒数第一)
print(loss_history[-2])   # 0.3   倒数第二个

# ===== 切片(获取一段连续的元素)=====
print(loss_history[1:4])  # [0.7, 0.5, 0.3]  索引1到3(不含4)
print(loss_history[:3])   # [0.9, 0.7, 0.5]  从开头到索引2
print(loss_history[2:])   # [0.5, 0.3, 0.15] 从索引2到末尾

# ===== 修改元素 =====
loss_history[0] = 0.95   # 把第一个值从 0.9 改为 0.95

# ===== 列表长度 =====
print(len(loss_history))  # 5  列表中有5个元素
列表常用方法

列表自带了很多实用的"工具"(方法),可以方便地增删改查。

Python — 列表方法
losses = [0.8, 0.6, 0.4, 0.9, 0.3]

# append() — 在末尾添加一个元素
losses.append(0.2)          # [0.8, 0.6, 0.4, 0.9, 0.3, 0.2]

# insert() — 在指定位置插入元素
losses.insert(0, 1.0)         # 在索引0处插入1.0
# [1.0, 0.8, 0.6, 0.4, 0.9, 0.3, 0.2]

# remove() — 删除第一个匹配的值
losses.remove(0.9)           # 删除值为0.9的元素

# pop() — 弹出指定位置的元素(默认最后一个)
last_loss = losses.pop()     # 弹出并返回最后一个元素 0.2
first_loss = losses.pop(0)    # 弹出并返回第一个元素 1.0

# sort() — 排序(默认升序)
losses.sort()                 # [0.3, 0.4, 0.6, 0.8]
losses.sort(reverse=True)    # [0.8, 0.6, 0.4, 0.3] 降序

# len() — 获取列表长度
print(len(losses))             # 4
列表推导式

列表推导式是 Python 的"语法糖" —— 用一行代码就能创建列表,比写 for 循环更简洁。AI 生成的代码中大量使用这种写法。

Python — 列表推导式
# ===== 基本语法:[表达式 for 变量 in 可迭代对象] =====

# 传统写法
squares = []
for x in range(6):
    squares.append(x ** 2)
# squares = [0, 1, 4, 9, 16, 25]

# 推导式写法(一行搞定!)
squares = [x ** 2 for x in range(6)]
# 结果: [0, 1, 4, 9, 16, 25]

# ===== 带条件的推导式 =====
# 只保留偶数的平方
even_squares = [x ** 2 for x in range(10) if x % 2 == 0]
# 结果: [0, 4, 16, 36, 64]

# ===== AI 场景:处理损失历史 =====
raw_losses = [0.9, 0.7, 0.5, 0.3, 0.15, 0.08]
# 筛选出 loss > 0.2 的轮次
high_loss = [l for l in raw_losses if l > 0.2]
print(high_loss)  # [0.9, 0.7, 0.5, 0.3]

# 将所有损失值四舍五入到2位小数
rounded = [round(l, 2) for l in raw_losses]
print(rounded)   # [0.9, 0.7, 0.5, 0.3, 0.15, 0.08]
AI 协作提示

当 AI 生成包含列表或字典的代码时,你应重点关注:数据从哪里来、如何被修改、最终流向哪里。这是审查 AI 代码正确性的核心思路。例如,检查 append() 是否在正确的位置被调用,切片范围是否合理。

字典(Dictionary)详解

如果说列表是"带编号的收纳架",那字典就是"带标签的收纳柜"。每个物品都有一个唯一的标签(键,key),通过标签就能快速找到对应的物品(值,value)。

概念解释:什么是字典?

字典是一种键值对(key-value)的存储结构。用花括号 {} 创建,键和值之间用冒号 : 分隔。在 AI 开发中,字典是最常用的配置管理方式 —— 模型的超参数、训练设置等通常都用字典来存储。

Python — 字典基础
# ===== 创建字典 =====
model_config = {
    "learning_rate": 0.001,    # 键: 学习率, 值: 0.001
    "batch_size": 32,          # 键: 批大小, 值: 32
    "epochs": 100,              # 键: 训练轮数, 值: 100
    "optimizer": "adam",       # 键: 优化器, 值: "adam"
    "use_gpu": True             # 键: 是否用GPU, 值: True
}

# ===== 访问值 =====
print(model_config["learning_rate"])  # 0.001
print(model_config["optimizer"])      # adam

# ===== 修改值 =====
model_config["epochs"] = 200             # 把训练轮数改为200
model_config["learning_rate"] = 0.0005     # 调整学习率

# ===== 添加新的键值对 =====
model_config["momentum"] = 0.9             # 新增动量参数

# ===== 删除键值对 =====
del model_config["momentum"]              # 删除 momentum

# 安全访问(键不存在时不报错,返回默认值)
lr = model_config.get("lr", 0.01)  # 键"lr"不存在,返回默认值0.01
print(lr)  # 0.01
遍历字典的 3 种方式
Python — 遍历字典
config = {
    "lr": 0.001,
    "batch_size": 32,
    "epochs": 100
}

# 方式1:只遍历键(keys)
for key in config:
    print(key)
# 输出: lr, batch_size, epochs

# 方式2:只遍历值(values)
for value in config.values():
    print(value)
# 输出: 0.001, 32, 100

# 方式3:同时遍历键和值(最常用!)
for key, value in config.items():
    print(f"{key} = {value}")
# 输出:
# lr = 0.001
# batch_size = 32
# epochs = 100
注意:字典的键必须是不可变类型

字典的键可以是字符串、数字、元组,但不能是列表或字典(因为它们是可变的)。尝试用列表做键会报 TypeError。另外,字典从 Python 3.7 开始保证插入顺序。

练习题 1.1
  1. 创建一个列表 temperatures,包含一周7天的气温(如 [28, 30, 27, 32, 29, 31, 26]),使用切片获取前3天和后3天的气温,并计算平均气温。
  2. 创建一个字典 student,包含 "name""age""major" 三个键。添加一个新键 "grade",然后使用 items() 遍历并打印所有信息。
  3. 使用列表推导式,从列表 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 中筛选出所有能被3整除的数,并将它们乘以10。

1.2 程序控制逻辑

如果说变量和数据是程序的"食材",那控制逻辑就是"菜谱的步骤"。通过条件判断和循环,你可以让程序根据不同情况做出不同的反应,或者重复执行某些操作。

条件语句 if-elif-else

条件语句让程序能够"做判断"。就像你出门前会看天气:如果下雨就带伞,否则就不带。Python 用 ifelifelse 三个关键字来实现多分支判断。

Python — 条件语句基础
# ===== 基本语法结构 =====
accuracy = 0.92

if accuracy >= 0.95:                    # 条件1:准确率 >= 95%
    print("模型表现优秀!可以部署")
elif accuracy >= 0.85:                  # 条件2:准确率 >= 85%
    print("模型表现良好,可继续优化")   # ← 命中这个分支
elif accuracy >= 0.70:                  # 条件3:准确率 >= 70%
    print("模型表现一般,需要调参")
else:                                  # 以上条件都不满足
    print("模型表现不佳,建议重新设计")
模型表现良好,可继续优化
Python — 逻辑运算符组合条件
# ===== and:两个条件都必须满足 =====
loss = 0.08
acc = 0.96
if loss < 0.1 and acc > 0.95:
    print("训练完成,模型达到目标!")

# ===== or:至少一个条件满足即可 =====
gpu_available = False
tpu_available = True
if gpu_available or tpu_available:
    print("可以使用加速硬件训练")

# ===== not:取反 =====
is_overfitting = False
if not is_overfitting:
    print("模型没有过拟合,继续训练")

# ===== 嵌套条件 =====
model_type = "cnn"
dataset_size = 50000

if model_type == "cnn":                    # 外层:判断模型类型
    if dataset_size > 10000:             # 内层:判断数据量
        print("数据充足,CNN 可以发挥优势")
    else:
        print("数据量不足,建议数据增强或换模型")
elif model_type == "transformer":
    print("Transformer 模型需要更多数据")
学习技巧:注意缩进!

Python 用缩进(通常是4个空格)来表示代码块的层次关系,而不是用大括号 {}。缩进错误是新手最常见的 Bug 之一。建议在编辑器中设置 Tab 键自动转为4个空格。

for 循环

for 循环用于遍历一个序列(列表、字符串、range 等),对每个元素执行相同的操作。就像你逐个检查流水线上的产品。

Python — for 循环基础
# ===== 遍历列表 =====
models = ["ResNet", "BERT", "GPT"]
for model in models:
    print(f"正在加载模型: {model}")

# ===== range() 函数详解 =====
# range(stop)       — 从 0 到 stop-1
for i in range(5):        # 0, 1, 2, 3, 4
    print(i, end=" ")

# range(start, stop) — 从 start 到 stop-1
for i in range(2, 6):      # 2, 3, 4, 5
    print(i, end=" ")

# range(start, stop, step) — 从 start 到 stop-1,步长为 step
for i in range(0, 10, 2):   # 0, 2, 4, 6, 8(偶数)
    print(i, end=" ")

# ===== enumerate() — 同时获取索引和值 =====
losses = [0.9, 0.7, 0.5, 0.3]
for epoch, loss in enumerate(losses):
    print(f"Epoch {epoch+1}: loss = {loss}")
# 输出:
# Epoch 1: loss = 0.9
# Epoch 2: loss = 0.7
# Epoch 3: loss = 0.5
# Epoch 4: loss = 0.3
Python — AI 场景:模拟训练 Epoch
# ===== AI 场景:模拟模型训练过程 =====
total_epochs = 5
loss = 1.0  # 初始损失值

for epoch in range(total_epochs):
    loss *= 0.7                    # 每轮损失降低30%
    accuracy = 1.0 - loss        # 模拟准确率提升
    print(f"Epoch {epoch+1}/{total_epochs} | "
          Loss: {loss:.4f} | Acc: {accuracy:.2%}")
Epoch 1/5 | Loss: 0.7000 | Acc: 30.00% Epoch 2/5 | Loss: 0.4900 | Acc: 51.00% Epoch 3/5 | Loss: 0.3430 | Acc: 65.70% Epoch 4/5 | Loss: 0.2401 | Acc: 75.99% Epoch 5/5 | Loss: 0.1681 | Acc: 83.19%
while 循环

while 循环在条件为 True 时一直执行,适合"不知道要循环多少次"的场景。就像你一直学习直到考试及格为止。

Python — while 循环
# ===== 基本语法 =====
count = 0
while count < 5:           # 当 count < 5 时持续执行
    print(count, end=" ")
    count += 1              # 一定要修改条件变量!否则死循环
# 输出: 0 1 2 3 4

# ===== AI 场景:持续训练直到损失达标 =====
loss = 1.0
step = 0
target_loss = 0.1

while loss > target_loss:     # 只要损失还没达标,就继续训练
    loss *= 0.7                # 模拟损失下降
    step += 1                  # 步数加1
    print(f"Step {step}: loss = {loss:.4f}")

print(f"经过 {step} 步训练,loss 降至 {loss:.4f},达标!")
Step 1: loss = 0.7000 Step 2: loss = 0.4900 Step 3: loss = 0.3430 Step 4: loss = 0.2401 Step 5: loss = 0.1681 Step 6: loss = 0.1176 Step 7: loss = 0.0824 经过 7 步训练,loss 降至 0.0824,达标!
概念解释:for 循环 vs while 循环

for 循环:知道要循环多少次(遍历列表、range)。while 循环:不知道要循环多少次,只知道终止条件(损失达标、用户输入正确密码)。在 AI 训练中,for 循环常用于固定 epoch 数的训练,while 循环常用于早停(Early Stopping)等动态终止策略。

break 和 continue

这两个关键字用于在循环中"跳过"或"提前退出",让循环控制更加灵活。

Python — break 和 continue
# ===== break:提前退出整个循环 =====
for epoch in range(100):
    loss = 1.0 / (epoch + 1)
    if loss < 0.05:              # 损失足够低了
        print(f"Epoch {epoch+1}: 提前停止!loss={loss:.4f}")
        break                     # 立即退出循环

# ===== continue:跳过本次,继续下一次 =====
for i in range(10):
    if i % 3 == 0:            # 跳过能被3整除的数
        continue
    print(i, end=" ")
# 输出: 1 2 4 5 7 8

# ===== AI 场景:早停机制(Early Stopping)=====
patience = 3          # 容忍连续3轮没有改善
wait = 0             # 等待计数器
best_loss = 999      # 最佳损失(初始设很大)

for epoch in range(20):
    loss = 0.5 / (epoch + 1) + 0.01 * epoch  # 模拟先降后升的损失

    if loss < best_loss:       # 如果当前损失比历史最佳更好
        best_loss = loss       # 更新最佳损失
        wait = 0               # 重置等待计数器
        print(f"Epoch {epoch+1}: 新最佳! loss={loss:.4f}")
    else:                      # 没有改善
        wait += 1               # 等待计数+1
        print(f"Epoch {epoch+1}: 无改善 ({wait}/{patience})")
        if wait >= patience:     # 超过容忍次数
            print(f"连续 {patience} 轮无改善,提前停止训练!")
            break             # 早停!
AI 协作提示

早停(Early Stopping)是 AI 训练中非常重要的技术,用于防止过拟合。当 AI 为你生成训练代码时,注意检查 break 的触发条件是否合理 —— 过早停止可能导致模型欠拟合,过晚停止则浪费时间。通常 patience 设为 3~5 比较合理。

练习题 1.2
  1. 编写一个程序,使用 for 循环和 if 语句,找出列表 [23, 45, 12, 67, 34, 89, 56] 中的最大值和最小值(不要使用内置的 max()min())。
  2. 使用 while 循环实现一个简单的"猜数字"游戏:设定一个目标数字(如 42),让用户不断输入猜测值,给出"大了"或"小了"的提示,直到猜对为止。
  3. 使用 for 循环和 enumerate(),遍历模型准确率列表 [0.60, 0.72, 0.81, 0.88, 0.91, 0.93, 0.94, 0.94, 0.95],找出准确率首次超过 0.90 的轮次。

1.3 函数

什么是函数?

想象你有一份蛋糕食谱:上面写着需要哪些原料、按什么步骤操作。每次你想做蛋糕,只需要按照食谱来,不用重新发明做法。在编程中,函数就是"食谱" —— 把一段有用的代码封装起来,需要时直接调用

概念解释:函数 = 食谱/公式

函数由三部分组成:输入(参数) = 原料,处理过程(函数体) = 制作步骤,输出(返回值) = 做好的蛋糕。定义一次,可以反复使用。这避免了代码重复,让程序更清晰、更易维护。

定义和调用函数
Python — 函数基础
# ===== 定义函数的基本结构 =====
def calculate_accuracy(correct, total):
    """计算分类准确率

    Args:
        correct: 正确预测的样本数
        total: 总样本数
    Returns:
        准确率(0到1之间的浮点数)
    """
    if total == 0:          # 防止除以零
        return 0
    return correct / total  # 返回计算结果

# ===== 调用函数 =====
acc = calculate_accuracy(92, 100)
print(f"准确率: {acc:.2%}")  # 准确率: 92.00%

# ===== 函数命名规范 =====
# 好的命名:动词开头,描述函数做什么
def train_model(data): ...     # ✓ 清晰
def load_dataset(path): ...   # ✓ 清晰
def tm(d): ...                # ✗ 太简短,难以理解
参数详解

参数是函数的"输入接口",不同类型的参数让函数更加灵活。

Python — 函数参数
# ===== 1. 位置参数(必须按顺序传入)=====
def train_model(data, epochs, lr):
    print(f"用 {data} 训练 {epochs} 轮, 学习率={lr}")

train_model("images", 10, 0.001)  # 必须按顺序传入3个参数

# ===== 2. 默认参数(不传就用默认值)=====
def train_model(data, epochs=10, lr=0.001):
    print(f"用 {data} 训练 {epochs} 轮, 学习率={lr}")

train_model("images")                # 使用默认值:10轮, lr=0.001
train_model("images", epochs=50)     # 只覆盖 epochs

# ===== 3. 关键字参数(用参数名指定,顺序无关)=====
train_model(lr=0.01, data="text", epochs=20)  # 顺序无关

# ===== 4. 可变参数 *args(接收任意数量的位置参数)=====
def compare_models(*accuracies):
    """比较多个模型的准确率"""
    for i, acc in enumerate(accuracies):
        print(f"模型{i+1} 准确率: {acc:.2%}")
    print(f"最佳: {max(accuracies):.2%}")

compare_models(0.85, 0.92, 0.88, 0.95)  # 传入任意数量

# ===== 5. 可变关键字参数 **kwargs(接收任意数量的关键字参数)=====
def train_with_config(data, **config):
    """使用配置字典训练模型"""
    print(f"数据: {data}")
    for key, value in config.items():
        print(f"  {key} = {value}")

train_with_config("images", epochs=50, lr=0.001, batch_size=32)
返回值
Python — 返回值
# ===== return 语句 =====
def calculate_metrics(correct, total, loss):
    accuracy = correct / total  # 计算准确率
    return accuracy               # 返回一个值

acc = calculate_metrics(90, 100, 0.3)
print(acc)  # 0.9

# ===== 返回多个值(元组解包)=====
def evaluate_model(predictions, labels):
    """评估模型,返回多个指标"""
    correct = sum(1 for p, l in zip(predictions, labels) if p == l)
    total = len(labels)
    accuracy = correct / total
    error_rate = 1.0 - accuracy
    return accuracy, error_rate, correct  # 返回多个值(实际是元组)

# 元组解包:用多个变量接收返回值
acc, err, cnt = evaluate_model([1,0,1,1], [1,0,0,1])
print(f"准确率: {acc:.2%}, 错误率: {err:.2%}, 正确数: {cnt}")
# 输出: 准确率: 75.00%, 错误率: 25.00%, 正确数: 3
变量作用域
Python — 变量作用域
# ===== 局部变量 vs 全局变量 =====
global_lr = 0.001  # 全局变量(在函数外定义)

def train():
    local_epoch = 10  # 局部变量(在函数内定义)
    print(f"内部 - 全局lr: {global_lr}")   # ✓ 可以读取全局变量
    print(f"内部 - 局部epoch: {local_epoch}") # ✓ 可以读取局部变量

train()
print(global_lr)     # ✓ 全局变量可以在函数外访问
# print(local_epoch)  # ✗ 报错!局部变量在函数外不可见

# ===== global 关键字:在函数内修改全局变量 =====
counter = 0

def increment():
    global counter      # 声明要修改的是全局变量
    counter += 1       # 修改全局变量

increment()
increment()
print(counter)  # 2
注意:谨慎使用 global

过度使用 global 会让代码难以调试和维护。在 AI 项目中,建议用类(Class)的属性来管理共享状态,而不是全局变量。好的函数应该是"自包含"的 —— 只通过参数接收输入,只通过返回值输出结果。

Lambda 表达式

Lambda 是一种"匿名函数" —— 没有名字、只有一行的简单函数。常与 map()filter() 配合使用。

Python — Lambda 表达式
# ===== 普通函数 vs Lambda =====
# 普通函数
def square(x):
    return x ** 2

# Lambda(等价写法,一行搞定)
square = lambda x: x ** 2
print(square(5))  # 25

# ===== 配合 map() 使用(对每个元素应用函数)=====
numbers = [3, 1, 4, 1, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # [9, 1, 16, 1, 25]

# ===== 配合 filter() 使用(筛选满足条件的元素)=====
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)    # [4]

# ===== AI 场景:对损失列表做归一化 =====
losses = [0.9, 0.7, 0.5, 0.3, 0.1]
max_loss = max(losses)
normalized = list(map(lambda l: l / max_loss, losses))
print(normalized)  # [1.0, 0.778, 0.556, 0.333, 0.111]
学习技巧:什么时候用 Lambda?

当函数逻辑很简单(只有一行表达式),且只需要临时使用一次时,用 Lambda。如果逻辑复杂或需要复用,还是写普通函数更清晰。AI 生成的代码中 Lambda 出现频率很高,你需要能读懂它,但不一定要自己写。

AI 协作提示

在审查 AI 生成的函数代码时,重点关注:函数的输入是什么、输出是什么、中间有没有意外的副作用。比如检查函数是否修改了传入的列表(这可能导致难以发现的 Bug)。好的函数应该像"纯函数"一样:相同输入永远产生相同输出。

练习题 1.3
  1. 编写函数 compute_f1(precision, recall),根据精确率和召回率计算 F1 分数。公式:F1 = 2 * precision * recall / (precision + recall)。注意处理分母为零的情况。
  2. 编写函数 find_best_threshold(losses, thresholds),接收一个损失列表和一组阈值列表,返回使准确率最高的阈值。使用 *args 或列表推导式。
  3. 使用 Lambda 和 filter(),从一个包含模型名称的列表 ["resnet50", "bert_base", "gpt2", "vgg16", "efficientnet"] 中筛选出包含数字的名称。

1.4 面向对象编程(OOP)

什么是面向对象?

想象你是一位汽车设计师。你先画一张设计图纸(类,Class),图纸上标注了汽车有几个轮子、什么颜色的漆、能跑多快。然后工厂根据这张图纸,生产出一辆辆真实的汽车(对象,Object)。每辆汽车都是独立的,有自己的状态。

概念解释:类 = 图纸,对象 = 产品

类(Class)是创建对象的模板/蓝图,定义了对象有哪些属性(数据)和方法(行为)。对象(Object)是根据类创建出来的具体实例。在 AI 框架(如 PyTorch)中,每个神经网络模型都是一个类,你创建的每个具体模型就是一个对象。

类和对象
Python — 类的基本结构
# ===== 定义一个类 =====
class SimpleModel:
    """一个简单的AI模型类"""

    # __init__ 是构造方法 —— 创建对象时自动调用
    # self 代表"这个对象自己"
    def __init__(self, input_size, hidden_size, output_size):
        # self.属性 = 实例属性(每个对象各自拥有)
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.output_size = output_size
        self.is_trained = False  # 默认未训练
        print(f"模型已创建: {input_size}{hidden_size}{output_size}")

    # 实例方法 —— 定义对象能做什么
    def forward(self, x):
        """前向传播:数据从输入流向输出"""
        hidden = [v * 0.5 for v in x]   # 模拟隐藏层计算
        output = sum(hidden) / len(hidden)  # 模拟输出层
        return output

    def train(self):
        """训练模型"""
        self.is_trained = True
        print("模型训练完成!")

    # __str__ 方法定义了用 print() 打印对象时的显示内容
    def __str__(self):
        return f"SimpleModel({self.input_size}, {self.hidden_size}, {self.output_size})"

# ===== 创建对象(实例化)=====
model = SimpleModel(input_size=784, hidden_size=128, output_size=10)

# ===== 使用对象 =====
print(model)                     # 调用 __str__
result = model.forward([1.0, 2.0, 3.0])  # 调用方法
print(f"模型输出: {result}")
model.train()                      # 训练模型
print(model.is_trained)            # True
学习技巧:self 是什么?

self 代表"当前对象自己"。当你写 model.forward(data) 时,Python 实际上在调用 SimpleModel.forward(model, data) —— 自动把 model 作为第一个参数传入。所以类中每个方法的第一个参数都是 self,通过 self.xxx 来访问和修改对象自己的属性。

AI 核心模式:模拟 PyTorch 的 nn.Module

在真实的 AI 框架中,神经网络模型都遵循一个统一模式:__init__ 中定义网络结构(有哪些层),forward 中定义数据如何流经这些层。这是你必须理解的核心模板

Python — 模拟 PyTorch 模型模式
# ===== 模拟 PyTorch 的 nn.Module 模式 =====
class ImageClassifier:
    """图像分类模型 —— 模拟 PyTorch 的 nn.Module"""

    # __init__: 定义模型结构(有哪些层、多少个神经元)
    def __init__(self, num_classes=10):
        self.num_classes = num_classes
        self.layers = [
            {"type": "conv", "size": 32},
            {"type": "conv", "size": 64},
            {"type": "linear", "size": num_classes}
        ]
        self.is_built = True
        print(f"模型构建完成,共 {len(self.layers)} 层,输出 {num_classes} 类")

    # forward: 定义数据的前向传播路径
    def forward(self, x):
        """数据从输入逐层流向输出"""
        print(f"输入形状: {x}")
        for i, layer in enumerate(self.layers):
            print(f"  → 经过第{i+1}层 ({layer['type']}, size={layer['size'])")
        print(f"输出: {self.num_classes 个类别的概率")
        return [0.1] * self.num_classes  # 模拟输出

# ===== 完整的创建和使用流程 =====
model = ImageClassifier(num_classes=10)  # 1. 创建模型
output = model.forward("一张28x28的图片")    # 2. 前向传播
print(f"预测结果: {output}")
为什么 OOP 是重点?

在 PyTorch 中,每个神经网络都是一个继承自 nn.Module 的类。你必须写 __init__ 定义网络层,写 forward 定义数据流向。理解这个模式,你就能读懂并修改 AI 生成的任何模型代码。这是本课程最重要的知识点。

继承

继承允许你创建一个新类,复用已有类的功能并扩展新功能。就像"电动汽车"继承了"汽车"的所有属性(轮子、方向盘),同时新增了"电池"属性。

Python — 继承
# ===== 基类(父类)=====
class SimpleModel:
    def __init__(self, input_size, hidden_size, output_size):
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.output_size = output_size

    def forward(self, x):
        hidden = [v * 0.5 for v in x]
        return sum(hidden) / len(hidden)

    def __str__(self):
        return f"SimpleModel({self.input_size}, {self.hidden_size}, {self.output_size})"

# ===== 子类(继承父类)=====
class AdvancedModel(SimpleModel):
    """高级模型 —— 在简单模型基础上增加 Dropout"""

    def __init__(self, input_size, hidden_size, output_size, dropout=0.5):
        # super() 调用父类的 __init__,复用父类的初始化逻辑
        super().__init__(input_size, hidden_size, output_size)
        self.dropout = dropout  # 子类新增属性
        print(f"高级模型已创建,Dropout率={dropout}")

    # 方法重写:覆盖父类的 forward 方法
    def forward(self, x):
        hidden = [v * self.dropout for v in x]  # 使用 dropout
        return sum(hidden) / len(hidden)

    # 子类新增方法
    def summary(self):
        print(f"模型结构: {self.input_size}{self.hidden_size}{self.output_size}")
        print(f"Dropout: {self.dropout}")

# ===== 使用继承 =====
adv_model = AdvancedModel(784, 256, 10, dropout=0.3)
adv_model.summary()        # 调用子类新方法
print(adv_model)            # 调用继承的 __str__
result = adv_model.forward([1, 2, 3])  # 调用重写的 forward
封装

封装是"隐藏内部细节,只暴露安全的接口"。就像你用手机不需要知道内部电路怎么走,只需要会按按钮就行。在 Python 中,用私有属性@property 装饰器来实现封装。

Python — 封装
class TrainingConfig:
    """训练配置类 —— 通过封装保护关键参数"""

    def __init__(self):
        # 双下划线开头 = 私有属性(外部不能直接访问)
        self.__learning_rate = 0.001
        self.__max_epochs = 100
        self.__batch_size = 32

    # @property 装饰器:让私有属性可以通过"属性"方式安全访问
    @property
    def learning_rate(self):
        """获取学习率(getter)"""
        return self.__learning_rate

    # @xxx.setter 装饰器:设置属性值时进行验证
    @learning_rate.setter
    def learning_rate(self, value):
        """设置学习率(setter)—— 带验证逻辑"""
        if value <= 0:
            raise ValueError("学习率必须大于 0!")
        if value > 1:
            raise ValueError("学习率不能大于 1!")
        self.__learning_rate = value
        print(f"学习率已更新为: {value}")

    @property
    def max_epochs(self):
        return self.__max_epochs

    @max_epochs.setter
    def max_epochs(self, value):
        if value < 1:
            raise ValueError("训练轮数至少为 1!")
        self.__max_epochs = value

# ===== 使用封装 =====
config = TrainingConfig()

# 读取属性
print(config.learning_rate)  # 0.001(通过 @property 访问)

# 设置属性(会自动验证)
config.learning_rate = 0.0005  # ✓ 合法值
# config.learning_rate = -0.1  # ✗ 会报错:ValueError
# config.learning_rate = 2.0   # ✗ 会报错:ValueError

# 直接访问私有属性会失败(名称被改写)
# print(config.__learning_rate)  # ✗ 报错!
注意:Python 的"私有"不是绝对的

Python 的双下划线私有属性实际上是通过"名称改写"(name mangling)实现的,__lr 会被改写为 _ClassName__lr。所以严格来说仍然可以通过 config._TrainingConfig__learning_rate 访问。Python 的封装更多是"约定"而非"强制",靠的是开发者自觉。

学习技巧:OOP 的三要素

面向对象编程有三大核心概念:封装(隐藏细节、保护数据)、继承(复用代码、扩展功能)、多态(同一方法在不同类中有不同行为)。本节重点讲了封装和继承。在 AI 框架中,你经常看到继承(自定义模型继承 nn.Module)和封装(通过 property 保护超参数)。

练习题 1.4
  1. 创建一个 Dataset 类,包含 __init__(self, name, size)get_info()(返回数据集名称和大小)和 __str__() 方法。创建两个不同的 Dataset 对象并打印。
  2. 创建一个基类 BaseOptimizer,包含 __init__(self, lr)step() 方法。创建子类 Adam(BaseOptimizer),在 step() 中打印"Adam 更新参数,lr=xxx"。使用 super() 调用父类初始化。
  3. 创建一个 ModelConfig 类,使用私有属性和 @property 封装 dropout_rate(必须在 0 到 1 之间)。尝试设置非法值(如 1.5),观察报错信息。
02

数据处理三剑客:与 AI 协作的实战工具

AI 应用前 90% 的时间都在处理数据。掌握 NumPy、Pandas、Matplotlib 是为 AI 准备"弹药"并理解其输出的关键。

NumPy — 数值计算

NumPy 数组(ndarray)是所有张量运算的基础。图像在计算机中就是一个多维 NumPy 数组。理解其"广播机制"可以实现并行计算。

Python
import numpy as np

# 创建数组
a = np.array([1, 2, 3, 4])        # 一维数组
matrix = np.array([[1, 2], [3, 4]])  # 二维矩阵
zeros = np.zeros((3, 3))              # 3×3 全零矩阵
rand = np.random.rand(2, 3)          # 2×3 随机矩阵

# 数组运算(向量化,比循环快 100 倍)
scores = np.array([85, 92, 78, 95, 88])
print(scores.mean())    # 87.6  均值
print(scores.std())     # 标准差
print(scores.max())     # 95    最大值
print(np.argmax(scores))  # 3     最大值索引

# ★ 广播机制 — 不同形状的数组自动对齐运算
data = np.array([[1, 2], [3, 4], [5, 6]])
bias = np.array([10, 20])
print(data + bias)
# [[11 22]
#  [13 24]
#  [15 26]]

# 索引与切片
img = np.zeros((28, 28))        # 模拟 28×28 灰度图像
print(img[0:14, :])              # 上半部分
print(img.shape)                # (28, 28)

Pandas — 数据分析

重点掌握 DataFrame 和 Series 数据结构,以及数据读取、清洗、筛选和基本统计分析。这是处理表格数据(CSV、Excel)的标准工具,直接关系到输入 AI 的数据质量。

Python
import pandas as pd

# 创建 DataFrame
df = pd.DataFrame({
    "name": ["样本A", "样本B", "样本C", "样本D"],
    "feature_1": [1.2, 3.4, 2.1, 4.5],
    "feature_2": [5.6, 7.8, None, 9.0],  # 含缺失值
    "label": [0, 1, 0, 1]
})

# 读取文件(最常用操作)
# df = pd.read_csv("data.csv")
# df = pd.read_excel("data.xlsx")

# 数据概览
print(df.head(2))       # 前 2 行
print(df.info())         # 数据类型和缺失值
print(df.describe())     # 统计摘要

# ★ 数据清洗 — 处理缺失值
print(df.isnull().sum())              # 查看缺失值数量
df["feature_2"] = df["feature_2"].fillna(df["feature_2"].mean())  # 均值填充

# 数据筛选
high = df[df["feature_1"] > 2.0]          # 条件筛选
cols = df[["name", "label"]]             # 选择列

# 分组统计
print(df.groupby("label")["feature_1"].mean())
🤖 AI 协作提示

AI 生成的数据处理代码中,Pandas 操作是最常见的。你应重点关注:fillna() 如何处理缺失值、groupby() 如何聚合数据、筛选条件是否正确。数据质量直接决定 AI 模型的效果。

Matplotlib — 数据可视化

掌握基础绘图(折线图、柱状图、散点图),用于可视化分析结果和监控 AI 模型的训练过程(如绘制 Loss 曲线、准确率曲线)。

Python
import matplotlib.pyplot as plt

# ★ 绘制训练 Loss 曲线 — AI 训练中最常用的图
epochs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
train_loss = [0.9, 0.7, 0.5, 0.4, 0.3, 0.25, 0.2, 0.18, 0.15, 0.12]
val_loss = [0.85, 0.72, 0.55, 0.45, 0.38, 0.35, 0.33, 0.32, 0.31, 0.30]

plt.figure(figsize=(8, 5))
plt.plot(epochs, train_loss, 'b-', label='训练损失')
plt.plot(epochs, val_loss, 'r--', label='验证损失')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('模型训练过程')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

# 散点图 — 查看数据分布
x = [1, 2, 3, 4, 5]
y = [2.1, 3.9, 6.2, 7.8, 10.1]
plt.scatter(x, y, color='green', s=80)
plt.show()
03

与 AI 协同的实践方法与高级概念

贯穿"以 AI 为伴"的学习理念,并点明关键的高级概念,让你能读懂更 Pythonic 的 AI 生成代码。

项目驱动,AI 辅助

采用"项目驱动,AI 辅助"的学习模式。从设定一个简单的数据分析或自动化小目标开始,利用 AI 生成初始代码,你的重点在于理解代码意图、调试错误和优化逻辑。这比单纯学习语法更高效。

💡 推荐学习流程

第一步:向 AI 描述你的目标(如"帮我分析一份销售数据的趋势")→ 第二步:AI 生成初始代码 → 第三步:逐行阅读,标注不理解的部分 → 第四步:向 AI 提问,理解每一行 → 第五步:运行、调试、优化 → 第六步:总结学到的知识点。

模块与包管理

如何导入和使用第三方库(如用 pip 安装)。这是使用 AI 生态工具的基础。

Bash + Python
# 终端中安装第三方库
# pip install numpy pandas matplotlib scikit-learn

# Python 中导入
import numpy as np           # 标准别名
from pandas import DataFrame  # 导入特定类
from sklearn.model_selection import train_test_split  # 深层导入

# 查看已安装的包
# pip list
# pip show numpy

文件操作与异常处理

读写文件(CSV、JSON)和捕获处理程序运行中的错误,保证程序健壮性。

Python
import json

# ★ JSON — AI 配置和数据交换的标准格式
config = {
    "model": "resnet50",
    "batch_size": 32,
    "epochs": 100
}

# 写入 JSON
with open("config.json", "w", encoding="utf-8") as f:
    json.dump(config, f, indent=2)

# 读取 JSON
with open("config.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)
    print(loaded["model"])  # 'resnet50'

# ★ 异常处理 — 让程序不轻易崩溃
try:
    df = pd.read_csv("data.csv")
    result = df.describe()
except FileNotFoundError:
    print("错误:找不到数据文件,请检查路径")
except Exception as e:
    print(f"未知错误:{e}")
else:
    print("数据处理成功!")
finally:
    print("程序执行完毕。")

迭代器、生成器与装饰器

了解这些概念,有助于阅读更高效、更 Pythonic 的 AI 生成代码。无需深入编码,但需认识其语法模式。

Python
# ★ 生成器 — 按需生成数据,节省内存
def data_batch_generator(data, batch_size=32):
    """逐批生成数据,AI 训练中常用模式"""
    for i in range(0, len(data), batch_size):
        yield data[i:i+batch_size]

# 使用生成器
data = list(range(100))
for batch in data_batch_generator(data, batch_size=30):
    print(f"批次大小: {len(batch)}")

# ★ 装饰器 — 不修改函数代码的情况下增强功能
import time

def timer(func):
    """计时装饰器 — 监控函数执行时间"""
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} 耗时: {end-start:.2f}秒")
        return result
    return wrapper

@timer  # 使用装饰器
def train_model():
    time.sleep(1.5)  # 模拟训练

train_model()  # 输出: train_model 耗时: 1.50秒
🤖 AI 协作提示

AI 生成的代码中经常出现 yield(生成器)、@ 开头的装饰器语法。你不需要自己写这些,但必须能识别它们并理解其作用,这样才能正确审查 AI 代码。

04

衔接 AI:传统机器学习入门

了解传统机器学习是理解 AI 世界的重要背景。Scikit-learn 封装了经典算法,了解其统一模式有助于快速使用 AI 生成的 ML 代码。

传统 ML 的价值

在数据量小、需要模型可解释性时,传统 ML 仍是重要选择。Scikit-learn 是最经典的 Python 机器学习库,它封装了线性回归、决策树、随机森林、SVM 等经典算法。

场景推荐算法特点
预测连续值(房价、温度)线性回归简单、可解释性强
分类问题(垃圾邮件检测)逻辑回归 / 决策树速度快、易于理解
小数据集、高精度需求随机森林 / SVM鲁棒性强、泛化好
数据量充足、复杂模式深度学习需要 GPU、大量数据

Scikit-learn 实战

Python
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report

# 1. 加载数据
iris = load_iris()
X = iris.data      # 特征矩阵 (150×4)
y = iris.target    # 标签 (150,)

# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 3. 实例化模型
model = RandomForestClassifier(n_estimators=100)

# 4. 拟合(训练)
model.fit(X_train, y_train)

# 5. 预测
y_pred = model.predict(X_test)

# 6. 评估
print(f"准确率: {accuracy_score(y_test, y_pred):.2%}")
print(classification_report(y_test, y_pred))

统一模式:实例化 → 拟合 → 预测

Scikit-learn 的所有算法都遵循同一个模式。掌握这个模式,你就能快速使用 AI 生成的任何 ML 代码。

Python — 统一模式
# ★ Scikit-learn 的统一模式(所有算法通用)

# 第一步:实例化(选择算法并设置参数)
from sklearn.linear_model import LinearRegression
model = LinearRegression()

# 第二步:拟合(用训练数据学习规律)
model.fit(X_train, y_train)

# 第三步:预测(对新数据做出判断)
predictions = model.predict(X_test)

# 换一个算法?只需改第一步!
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()
model.fit(X_train, y_train)
predictions = model.predict(X_test)
🤖 AI 协作提示

当 AI 为你生成机器学习代码时,你只需检查三件事:① 数据是否正确划分了训练集和测试集?② fit() 的输入特征和标签是否对应?③ 评估指标是否合理?掌握了这个思路,你就能成为 AI 代码的合格"质检员"。

🎉 课程总结

恭喜你完成了本课程!你已经掌握了 AI 时代 Python 协作者的核心能力:能读懂 AI 生成的代码(语法 + OOP)、能为 AI 准备高质量数据(NumPy + Pandas)、能可视化分析结果(Matplotlib)、能管理项目和处理异常、能快速上手传统 ML(Scikit-learn)。记住:你的目标不是成为熟练的编码者,而是成为能精准向 AI 描述需求、能批判性评估和优化其代码输出的"智能时代协作者"