> **GESP等级：三级 | 考级考点：GESP Python 三级**

# 第10节教案 —— 字符串方法下：find/replace/count/len/startswith（60分钟）

> **GESP 考点**：#9 字符串（方法综合应用）
> **教学形式**：上机实操课 —— 每人一台电脑，跟着敲代码、看效果
> **前置基础**：第10节「字符串方法上」—— 已学 upper/lower/strip/isalpha/isdecimal/split/join
> **配套文件**：`第10节_字符串方法下.py` / `课堂练习册_第10节_字符串方法下.md` / `课后练习卡_第10节_字符串方法下.md`

---

## 一、GESP 知识映射表

| GESP 一级考点 | 大纲编号 | 本关对应教学环节 | 身体锚点 | 达标标准 |
|-------------|---------|----------------|---------|---------|
| **字符串索引与查找** | 1.5.1 | `find()` 方法精讲：在字符串中查找子串位置，找不到返回 -1 | "find = 在书里找某个字在第几页" | 孩子能正确说出 `find()` 返回的是下标索引，找不到返回 -1 |
| **字符串替换** | 1.5.2 | `replace()` 方法精讲：将字符串中的指定子串替换为新子串 | "replace = 把旧字换成新字" | 孩子能写出 `replace(旧, 新)` 并理解原字符串不变 |
| **字符串统计** | 1.5.1 | `count()` 方法精讲：统计子串在字符串中出现的次数 | "count = 数学上的数一数" | 孩子能正确计算 `count()` 的返回结果 |
| **字符串长度** | 1.1.1 | `len()` 函数：获取字符串的字符个数（含空格） | "len = length = 长度" | 孩子能区分 `len()`（总字符数）和 `count()`（子串出现次数） |
| **字符串判断** | 1.5.1 | `startswith()` / `endswith()` 判断字符串开头/结尾 | "starts with = 以什么开头，像查字典" | 孩子能正确使用 `startswith()` 和 `endswith()` 做判断 |

---

## 二、教学目标

### 2.1 知识目标（下课后孩子能回答）

- 说出 `find()` 的作用是"找位置"，返回找到的第一个下标，找不到返回 -1
- 说出 `replace()` 的作用是"换内容"，把旧字符串换成新字符串
- 说出 `count()` 的作用是"数次数"，统计子串出现了几次
- 说出 `startswith()` 的作用是"判断以什么开头"，返回 True/False

### 2.2 技能目标（下课后孩子能做到）

- 独立写出 `"hello".find("e")` 并正确说出结果是 1
- 用 `replace("l","w")` 把 "hello" 变成 "hewwo"
- 用 `"banana".count("a")` 数出香蕉里有几个 a
- 用 `len()` 获取任意字符串的长度
- 用 `startswith()` 判断文件名是否以特定前缀开头

### 2.3 情感目标（下课后孩子能感受到）

- "原来字符串方法这么好用！"—— 建立方法工具箱的感觉
- "字符串不只是文字，还能像数据一样操作"—— 理解字符串即数据
- "编程就是组合这些方法解决问题"—— 培养组合思维

---

## 三、教学节奏总览（60分钟分钟级拆解）

| 时间段 | 时长 | 环节名称 | 核心活动 | 教学形式 | GESP考点 |
|--------|------|---------|---------|---------|-----------|
| 0-3分钟 | 3' | 复习导入 | "上节课学了什么方法？" → 回忆 upper/lower/split/join → "今天我们学更多好用的工具！" | 问答+投影 | #9导入 |
| 3-10分钟 | 7' | 情景导入 | "字符串里找东西(find)和换东西(replace)" → 课本比喻 → 全文字游戏预热 | 讲授+身体锚点 | #9铺垫 |
| 10-14分钟 | 4' | ①find()精讲 | "hello".find("e") → 返回1 → 找不到返回-1 → 索引第几个 | 演示+实操 | #9 |
| 14-19分钟 | 5' | ②replace()精讲 | "hello".replace("l","w") → hewwo → 只换第一个/全部换 | 演示+实操 | #9 |
| 19-23分钟 | 4' | ③count()精讲 | "banana".count("a") → 3次 → 对比len() | 演示+实操 | #9 |
| 23-26分钟 | 3' | ④startswith/endswith | "hello".startswith("he") → True → 判断文件名后缀 | 演示+实操 | #9 |
| 26-30分钟 | 4' | ⑤len()总长度 | len("hello") → 5 → 对比count() | 演示+实操 | #9 |
| 30-40分钟 | 10' | 综合演示 | turtle颜色名用find查找 / 用replace改名 / 颜色列表处理 | 教师演示 | #9 |
| 40-43分钟 | 3' | 填空抢答 | 方法功能填空 → 全班举手抢答 | 互动问答 | #9 |
| 43-48分钟 | 5' | 实操①补全代码 | 给出不完整代码，补全字符串方法调用 | 个人实操 | #9 |
| 48-55分钟 | 7' | 实操②综合创意 | 处理颜色列表：查找包含"blue"的颜色、改名 | 小组合作 | #9 |
| 55-58分钟 | 3' | 小测 | "banana".count("a")=? 口答 + 记忆钩子齐读 | 全班问答 | #9 |
| 58-60分钟 | 2' | 总结+发课后练习 | 回顾五个方法 → 齐读记忆钩子 → 发课后练习卡 | 总结 | #9 |

---

## 四、详细教学过程

### 第一阶段：导入 —— 复习 + 情景创设（0-10分钟）

#### 4.1.1 复习导入（0-3分钟）

**老师开场白**（面带笑容，语调轻松）：

> "同学们好！上节课我们学了字符串方法上——还记得方法是什么吗？"
>
> 引导回答：**对字符串调用的函数！**
>
> "上节课我们学了哪些方法？谁来说一个？"
>
> 引导举手回答：`upper()`、`lower()`、`strip()`、`isalpha()`、`isdecimal()`、`split()`、`join()`

**快速口答复习**：

| 老师问 | 学生答 |
|--------|--------|
| "'Hello'.upper() 结果是？" | "HELLO" |
| "'HELLO'.lower() 结果是？" | "hello" |
| "'  hello  '.strip() 结果是？" | "hello" |
| "'123'.isdecimal() 结果是？" | "True" |
| "'a b c'.split() 结果是？" | "['a', 'b', 'c']" |

> "好！上节课的方法大家记得不错。今天我们要继续学字符串的更多方法——这节课学的方法更偏向**查找、替换、统计**。准备好迎接新工具了吗？"

#### 4.1.2 情景类比导入（3-10分钟）

> "同学们，你在看书的时候，如果想在书里找一个字在第几页，你会怎么办？"
>
> 引导回答：翻目录、一页一页翻、用页码……
>
> "那如果一本书有300页，让你找'梦'字在第几页，一页一页翻是不是很累？"
>
> "现在好了——Python的字符串有一个方法叫 `find()`，就像有一双火眼金睛，一眼就能看到要找的字符在哪个位置！"

**板书（或PPT展示）**：

```
📖 在书里找字 → 翻页查找  🐍 Python → 字符串.find(要找的字)
```

> "那如果你想改书里的一句话呢——比如'小明很聪明'你想改成'小红很聪明'。一页一页改也很累对吧？"
>
> "Python的 `replace()` 方法，就像'一键替换'——输入旧字和新字，嗖一下就全改好了！"

**板书**：

```
🖊️ 在书里改字 → 逐页修改  🐍 Python → 字符串.replace(旧字, 新字)
```

> "今天我们就来学这五个字符串新工具——"

**展示本课五个方法名称（投影）**：

```
🧰 字符串方法工具箱 · 下
┌─────────────┬────────────────┬──────────────┐
│   方法名     │     作用       │   记忆锚点    │
├─────────────┼────────────────┼──────────────┤
│  find()     │  找位置        │  找到第几个字符 │
│  replace()  │  换内容        │  旧字→新字    │
│  count()    │  数次数        │  出现几次     │
│  startswith()│ 判断开头      │  以什么开头   │
│  len()      │  求长度        │  一共多少字符  │
└─────────────┴────────────────┴──────────────┘
```

**记忆钩子首次亮相**（全班齐读）：

> **"find()找位置  replace()换内容  count()数次数"**

---

### 第二阶段：知识点精讲 —— 五大方法逐个学（10-30分钟）

> **重要教学原则**：每个方法遵循"看代码 → 敲一遍 → F5跑 → 看结果 → 改参数再跑"的循环。

#### 4.2.1 精讲①：find()——找位置（10-14分钟）

**打开代码文件** `第10节_字符串方法下.py`

> "请打开代码文件，找到第1段代码——find() 演示。"

```python
# ===== find() 演示 =====
s = "hello"
print(s.find("e"))      # 找"e"在哪个位置 → 1
print(s.find("l"))      # 找"l"在哪个位置 → 2（第一个l）
print(s.find("z"))      # 找不到 → -1
```

**老师投影展示并逐行讲解**：

> "看第1行：`s = 'hello'` —— 一个简单的字符串。"
>
> "第2行：`s.find('e')` —— 在s里找'e'，它告诉你：'e'在第1个位置。"
>
> "这里有个重要的点——**计算机数数从0开始**！h在第0位，e在第1位，l在第2位，l在第3位，o在第4位。"

**板书**：

```
  h   e   l   l   o
  0   1   2   3   4  ← 索引（位置编号）
      ↑ "e"在第1位
```

> "第3行：`s.find('l')` —— 找到的是2，因为第一个l在第2位。第二个l在第3位它不管——find只找第一个！"
>
> "第4行：`s.find('z')` —— 字符串里没有'z'，它返回什么？**-1**！记住——找不到返回 -1。"

**让孩子自己操作**：

> "把你的代码找到这一段，按F5跑一下。看到结果了吗？"

**追问**：

> "如果我写 `s.find('llo')`，会返回什么？"
>
> 引导回答：**2**！因为'llo'从第2位开始。

> "对！find不仅可以找一个字符，还能找一串字符——找的是这串字符**第一次出现的位置**。"

**板书记忆钩子**：

```
find(要找的) → 返回位置（索引），找不到返回 -1
find只找第一次出现的位置！
计算机从0开始数！
```

#### 4.2.2 精讲②：replace()——换内容（14-19分钟）

> "好，现在学第二个方法——`replace()`，把字符串里的旧内容换成新内容。"

```python
# ===== replace() 演示 =====
s = "hello"
print(s.replace("l", "w"))       # hewwo（所有l都换成w）
print(s.replace("l", "w", 1))    # hewlo（只换第1个l）
print(s)                         # 原字符串没变 → "hello"
```

**老师逐步演示**：

> "第一行 `s.replace('l', 'w')` —— 把字符串里所有的'l'换成'w'。结果是 'hewwo'。"
>
> "注意：默认是**全部替换**，所有的l都被替换成了w。"

> "第二行 `s.replace('l', 'w', 1)` —— 多了一个参数1，意思是**只替换第1个l**。结果是 'hewlo'——第二个l没有变！"

**关键概念（原字符串不变）**：

> "注意第三行——我们直接打印 s，还是'hello'！"
>
> "**replace不会修改原字符串！** 它返回的是一个**新的字符串**。如果你要保存替换后的结果，需要用一个变量接住——"

```python
new_s = s.replace("l", "w")   # 新字符串 = "hewwo"
```

**身体锚点**：

> "replace = Re + place = 重新+放置 = 换掉。就像你把作业本上写错的字涂掉，写上正确的字——旧的没了，新的来了。"

**追问**：

> "如果我想把 'hello world' 里的空格换成逗号，怎么写？"
>
> 引导回答：`"hello world".replace(" ", ",")` → "hello,world"

> "如果我只想换第一个空格呢？"
>
> 引导回答：`"hello world nice".replace(" ", ",", 1)` → "hello,world nice"

**板书记忆钩子**：

```
replace(旧, 新) → 把旧的全部换成新的
replace(旧, 新, 次数) → 只换前几个
原字符串不变！要保存结果需要赋给新变量
```

#### 4.2.3 精讲③：count()——数次数（19-23分钟）

> "第三个方法——`count()`，用来数一数某个字符在字符串里出现了几次。"

```python
# ===== count() 演示 =====
s = "banana"
print(s.count("a"))          # 3（a出现了3次）
print(s.count("na"))         # 2（na出现了2次）
print(s.count("z"))          # 0（z没出现）
```

**老师**：

> "`'banana'` 里有几个 a？"
>
> 全班：**3个！**
>
> "对！b-a-n-a-n-a，三个a。`count('a')` 返回 3。"

> "问大家一个问题——`'banana'.count('na')` 是多少？"
>
> 引导回答：**2**！因为 'na' 出现了两次——第2-3位和第4-5位。

> "`'banana'.count('z')` 呢？"
>
> 引导回答：**0**！因为没有z，一次都没出现。

**与find对比**：

> "find是找位置，count是数次数——find返回索引（一个数字），count返回次数（也是一个数字）。"
>
> "如果我用 `s.find('a')` 返回1（第一个a在第1位），`s.count('a')` 返回3（a出现了3次）——这两个方法返回的数字含义不同。"

**板书记忆钩子**：

```
count(要数的) → 返回出现的次数
找不到/没有就返回 0
count跟find的区别：find找位置，count数次数
```

#### 4.2.4 精讲④：startswith() / endswith()——判断开头/结尾（23-26分钟）

> "接下来学两个判断方法——`startswith()` 和 `endswith()`，用来判断字符串以什么开头、以什么结尾。"

```python
# ===== startswith() / endswith() 演示 =====
s = "hello.py"
print(s.startswith("he"))    # True
print(s.startswith("hel"))   # True
print(s.startswith("Hello")) # False（大小写敏感）
print(s.endswith(".py"))     # True
print(s.endswith(".txt"))    # False
```

**老师**：

> "假如你有一个文件名 `'hello.py'`，你想判断它是不是以 'he' 开头——用 `startswith('he')`，返回 True。"
>
> "你想判断它是不是 .py 文件——用 `endswith('.py')`，返回 True。"

**生活中类比**：

> "就像你检查自己有没有发烧——用体温计量体温。startswith 和 endswith 就是字符串的温度计——判断开头和结尾是不是你预期的样子。"

**大小写敏感**：

> "注意——'hello'.startswith('Hello') 是 False！因为 **startswith 和 endswith 都是大小写敏感的**。'H' 和 'h' 不一样！"

**追问**：

> "我有一堆文件名：'cat.jpg'、'dog.jpg'、'notes.txt'。怎么把图片文件选出来？"
>
> 引导回答：`文件名.endswith('.jpg')` → 返回True的就是图片！

**板书记忆钩子**：

```
startswith(开头) → 判断是否以...开头 → 返回 True/False
endswith(结尾)   → 判断是否以...结尾 → 返回 True/False
大小写敏感！'He' ≠ 'he'
```

#### 4.2.5 精讲⑤：len()——求长度（26-30分钟）

> "最后一个不是方法，是一个**函数**——`len()`。方法前面有点号，函数前面没有。`len()` 直接调用。"

```python
# ===== len() 演示 =====
s = "hello"
print(len(s))            # 5（5个字符）
print(len("banana"))     # 6
print(len("hello world")) # 11（空格也算一个字符）
print(len(""))           # 0（空字符串长度为0）
```

**老师**：

> "`len()` 是 length（长度）的缩写。它告诉你的字符串里一共有多少个字符——**包括空格**。"
>
> "'hello' 有5个字符，len返回5。'banana' 有6个字符，len返回6。"
>
> "'hello world' 中间有一个空格——总共11个字符，len返回11。"

**对比 len 和 count**：

> "有同学会问：`len('banana')` 和 `'banana'.count('a')` 有什么区别？"
>
> "**`len()` 数所有的字符**——不管是什么字符都算。**`count()` 只数你指定的那个字符**。"
>
> ```
> len("banana")      → 6（所有字符的总数）
> "banana".count("a") → 3（只有a的数量）
> ```

**板书**：

```
len(字符串) → 返回字符串的字符总数（包括空格和标点）
len是函数，不是方法——没有点号！
len数所有字符，count只数指定的字符
```

**快速练习**（全班举手回答）：

| 代码 | 结果 |
|------|------|
| `len("abc")` | 3 |
| `len("a b c")` | 5（两个空格） |
| `len("")` | 0 |
| `len("12345")` | 5 |

---

### 第三阶段：教师演示 —— turtle 颜色名实战（30-40分钟）

> **目的**：将新学的五个方法综合应用到 turtle 颜色处理中，展示实际用途。

#### 4.3.1 用 find 查找颜色名中的特定字符（30-34分钟）

**老师**：

> "现在到了最有趣的环节——我们把今天学的方法用在 turtle 的**颜色名**上！"
>
> "turtle 有很多颜色——'red'、'blue'、'green'、'yellow'、'purple'、'orange'……我们用字符串方法来处理这些颜色名字。"

```python
import turtle

# ===== 颜色列表 =====
colors = ["red", "blue", "green", "yellow", "purple", "orange", "pink", "brown", "black", "white"]
```

**演示1：查找包含特定字母的颜色**

```python
# 查找哪些颜色名字里包含字母 'e'
for c in colors:
    pos = c.find("e")
    if pos != -1:    # 如果找到了
        print(f"{c} 中包含 'e'，在第 {pos} 位")
    else:
        print(f"{c} 中不包含 'e'")
```

> "我们用 `find()` 遍历颜色列表，找到所有包含字母'e'的颜色——'red'在第2位有e，'green'在第3位有e，'yellow'在第4位有e……"

**演示2：用颜色名控制 turtle 颜色**

```python
t = turtle.Turtle()
t.shape("turtle")

# 用 for 循环演示不同颜色
for c in colors:
    t.color(c)
    t.forward(30)
```

> "实际上 turtle 的颜色名直接传进去就行。但我们今天要做的是——用字符串方法来分析这些颜色名！"

#### 4.3.2 用 replace 修改颜色名（34-37分钟）

**演示3：replace 批量改名**

```python
# 把所有颜色名中的 'e' 替换成 '3'
new_colors = []
for c in colors:
    new_name = c.replace("e", "3")
    new_colors.append(new_name)
    print(f"{c} → {new_name}")
```

> "看看替换后的效果——'red' 变成 'r3d'，'green' 变成 'gr33n'，'yellow' 变成 'y3llow'……"

**演示4：把颜色名中的 'blue' 统一替换**

```python
# 假如我们想把所有颜色名里的 'blue' 字样替换掉
name = "bluebird"
print(name.replace("blue", "red"))   # "redbird"
```

> "`replace()` 不仅可以换一个字符，还能换一串字符！"

#### 4.3.3 综合应用：分析颜色列表（37-40分钟）

> "现在我们把今天学的方法全部用上，分析这个颜色列表。"

```python
# ===== 综合演示 =====
colors = ["red", "blue", "green", "yellow", "purple", "orange", "pink", "brown", "black", "white"]

print("=== 颜色分析报告 ===")
for c in colors:
    length = len(c)                          # 长度
    has_e = c.find("e")                      # 找'e'的位置（-1表示没有）
    a_count = c.count("a")                   # 'a'出现了几次
    starts_b = c.startswith("b")             # 是不是以b开头？
    
    print(f"{c:8} | 长度:{length} | 含'e':{has_e} | a出现{a_count}次 | 以b开头:{starts_b}")
```

**输出效果**：

```
=== 颜色分析报告 ===
red      | 长度:3 | 含'e':1 | a出现0次 | 以b开头:False
blue     | 长度:4 | 含'e':3 | a出现0次 | 以b开头:True
green    | 长度:5 | 含'e':2 | a出现0次 | 以b开头:False
yellow   | 长度:6 | 含'e':4 | a出现0次 | 以b开头:False
purple   | 长度:6 | 含'e':3 | a出现0次 | 以b开头:False
orange   | 长度:6 | 含'e':5 | a出现1次 | 以b开头:False
pink     | 长度:4 | 含'e':-1| a出现0次 | 以b开头:False
brown    | 长度:5 | 含'e':-1| a出现0次 | 以b开头:True
black    | 长度:5 | 含'e':-1| a出现1次 | 以b开头:True
white    | 长度:5 | 含'e':3 | a出现0次 | 以b开头:False
```

> "哇！一行代码就把所有颜色的信息全算出来了！"
>
> "这五个方法组合起来，可以做出非常强大的字符串分析工具。"

**老师总结**：

> "你们有没有发现——今天学的方法，单独看都很简单。但是组合起来，就能做很复杂的事情。"
>
> "编程的秘诀就是这样——**把简单的方法组合起来，解决复杂的问题**。"

---

### 第四阶段：学生实操（40-55分钟）

#### 4.4.1 环节①：填空抢答——方法功能匹配（40-43分钟）

**老师投影题目**，全班举手抢答：

| # | 题目 | 答案 |
|---|------|------|
| 1 | `"hello".____("e")` → 返回 1 | `find` |
| 2 | `"hello".____("l", "w")` → "hewwo" | `replace` |
| 3 | `"banana".____("a")` → 3 | `count` |
| 4 | `____("hello")` → 5 | `len`（注意没有点号！） |
| 5 | `"hello".________("he")` → True | `startswith` |

**改错题**：

> "下面的代码有错误——谁来找出问题？"

```python
# 错误代码
s = "hello"
result = s.replace("l", "w")
print(s)       # 打印出来是什么？
```

> 引导回答：**还是 "hello"！** replace不会修改原字符串，要打印 result 变量！

**老师**：

> "对！`replace` 返回的是一个新字符串，原字符串不变。记住——**字符串是'不可变的'**，任何方法都不能修改原字符串，只能返回新字符串。"

#### 4.4.2 实操②：补全代码（43-48分钟）

> "现在轮到你们动手了。打开课堂练习册，完成练习1——补全代码。"

**题目来自 `课堂练习册_第10节_字符串方法下.md`**：

```python
# 练习1：补全代码
s = "hello python"

# ① 找 "python" 在 s 中的位置
pos = s.______("python")
print(pos)        # 应该输出 6

# ② 把空格替换成 "!"
new_s = s.______(" ", "!")
print(new_s)      # 应该输出 "hello!python"

# ③ 数一数 "o" 出现了几次
count_o = s.____("o")
print(count_o)    # 应该输出 2

# ④ 判断 s 是否以 "he" 开头
is_start = s.__________("he")
print(is_start)   # 应该输出 True

# ⑤ s 的长度
length = ____(s)
print(length)     # 应该输出 12
```

**老师巡视 5 分钟，重点检查**：
- `find` 的写法（不要写成 `find()` 括号里写对）
- `replace` 的参数顺序（旧在前，新在后）
- `count` 区分于 `len`
- `len()` 是函数，前面没有点号

**答案**：
```python
s.find("python")     # ①
s.replace(" ", "!")  # ②
s.count("o")         # ③
s.startswith("he")   # ④
len(s)               # ⑤
```

#### 4.4.3 实操③：颜色列表综合创意（48-55分钟）

> "最后一题——综合运用今天学的所有方法，处理颜色列表。"

**题目**：

```python
colors = ["red", "blue", "green", "yellow", "purple", "orange", 
          "pink", "brown", "black", "white", "gold", "silver"]
```

**任务 A（所有人都要做）**：找出所有以 'b' 开头的颜色

```python
for c in colors:
    if c.__________("b"):    # 补全
        print(c, "以b开头")
```

**任务 B（所有人都要做）**：找出所有包含 'e' 的颜色

```python
for c in colors:
    if c.____("e") != ____:  # 补全：不等于什么表示找到了？
        print(c, "包含e")
```

**任务 C（挑战，完成快的同学做）**：把所有颜色名中的 'e' 改成 '3'，生成新的列表

```python
new_colors = []
for c in colors:
    new_name = c.________("e", "3")   # 补全
    new_colors.append(new_name)
print(new_colors)
```

**任务 D（超级挑战，选做）**：找出所有长度恰好为5的颜色名

```python
for c in colors:
    if ____(c) == 5:    # 补全
        print(c, "长度是5")
```

**答案速查**：
- A: `c.startswith("b")`
- B: `c.find("e") != -1` 或 `c.count("e") > 0`
- C: `c.replace("e", "3")`
- D: `len(c) == 5`

---

### 第五阶段：小测 + 课堂总结（55-60分钟）

#### 4.5.1 口答小测（55-58分钟）

> "好，下课之前，老师问几个问题——举手回答！"

**Q1**：
> "`'banana'.count('a')` = ?"
>
> 预期回答：3！

**Q2**：
> "`'hello'.find('e')` 返回什么？"
>
> 预期回答：1（注意：是1不是2！计算机从0开始数）

**Q3**：
> "`'hello'.replace('l', 'w')` 返回什么？"
>
> 预期回答：hewwo

**Q4**：
> "`replace` 会修改原来的字符串吗？"
>
> 预期回答：不会！它返回一个新的字符串。

**Q5**：
> "`len` 和 `count` 有什么区别？"
>
> 预期回答：len 数所有字符的总数，count 只数指定的字符。

**Q6**：
> "`'apple.py'.endswith('.py')` 返回什么？"
>
> 预期回答：True

**Q7**：
> "如果在字符串中找不到要找的字符，`find()` 会返回什么？"
>
> 预期回答：-1

#### 4.5.2 关键记忆钩子齐读（58-59分钟）

**老师板书/投影**，全班齐读两遍：

```
🧰 字符串方法下 · 记忆钩子

find()   找位置  → "在字符串里找东西在第几位"
replace() 换内容  → "把旧的换成新的"
count()   数次数  → "数一数出现了几次"
startswith() 判断开头 → "以什么开头？"
endswith()   判断结尾 → "以什么结尾？"
len()     求长度  → "一共多少个字符？"
```

**全班齐读记忆钩子三遍**：

> **"find()找位置  replace()换内容  count()数次数"**

#### 4.5.3 发课后练习（59-60分钟）

> "这张练习卡回家做。回家跟爸爸妈妈说说今天学的五个方法——你来当小老师！"
>
> "下节课我们要学字符串的最后一个重要内容——**字符串格式化**，你会学会怎么用 f-string 把变量嵌入到字符串中。"
>
> "下节课见！"

---

## 五、板书设计

```
┌──────────────────────────────────────────────────────────────┐
│         第10节：字符串方法下 —— find/replace/count/len/startswith│
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  一、五大方法                                                │
│    s.find("要找的")  → 返回位置（索引），找不到=-1             │
│    s.replace("旧","新") → 返回新字符串，原串不变              │
│    s.replace("旧","新",次数) → 只替换前N个                   │
│    s.count("要数的") → 返回出现次数                          │
│    s.startswith("开头") → True/False                        │
│    s.endswith("结尾")   → True/False                        │
│    len(s)  → 返回字符总数（函数，没有点号！）                  │
│                                                              │
│  二、重要区别                                                │
│    find() vs count(): find找位置，count数次数                │
│    len() vs count(): len数总数，count只数指定的               │
│    方法前面有点号，函数（len）前面没有点号                    │
│                                                              │
│  三、字符串不可变                                            │
│    所有方法都不修改原字符串！                                 │
│    想要保存结果 → 用变量接住                                  │
│                                                              │
│  四、记忆钩子                                                │
│    "find()找位置  replace()换内容  count()数次数"            │
│    "startswith = 以什么开头"                                 │
│    "endswith = 以什么结尾"                                   │
│    "len = length = 长度"                                     │
└──────────────────────────────────────────────────────────────┘
```

---

## 六、故意犯错设计

| 序号 | 错误类型 | 错误代码 | 报错/错误结果 | 教学时机 | 教学目的 |
|------|---------|---------|-------------|---------|---------|
| ① | find拼写错 | `s.fynd("e")` | AttributeError: 'str' object has no attribute 'fynd' | find精讲时 | 方法名不能拼错 |
| ② | replace参数颠倒 | `s.replace("w","l")` | 结果不对（把w换成l，但字符串里没有w） | replace精讲时 | 参数顺序：旧在前，新在后 |
| ③ | replace以为改了原串 | `s.replace("l","w")`之后直接打印s | 打印出原字符串"hello"，不是"hewwo" | replace精讲时 | 原字符串不可变 |
| ④ | 误以为find返回-1是找到了 | 判断时写 `if s.find("z"):` | 认为-1是True（-1是True！0才是False） | find精讲时 | 应该用 `!= -1` 判断 |
| ⑤ | 把len当方法用 | `s.len()` | AttributeError | len精讲时 | len是函数不是方法 |
| ⑥ | count和len搞混 | 说"len('banana')返回a的数量" | 知识混淆 | 两者都讲完后对比 | 区分总数和指定数 |

---

## 七、课堂速查卡（老师口袋版）

### 7.1 课堂口令一览

| 环节 | 口令 | 目的 |
|------|------|------|
| 复习 | "上节课学的字符串方法有——？大写、小写、去空格……" | 回顾旧知 |
| find | "find = 在字符串里找东西，找到返回位置，找不到返回-1" | 核心概念 |
| replace | "replace = 把旧字换成新字，原字符串不变！" | 核心概念+不可变 |
| count | "count = 数一数出现了几次，没有就是0" | 核心概念 |
| len | "len = length = 长度，数所有字符，包括空格" | 核心概念 |
| 记忆钩子 | "find()找位置 replace()换内容 count()数次数" | 三遍齐读 |
| 字符串不可变 | "字符串是'不可变的'——方法只能返回新字符串，不能改原串" | 关键概念 |

### 7.2 巡视五查

| 检查项 | 怎么看 | 怎么改 |
|--------|--------|--------|
| find拼写 | `find` 写成 `fand`/`fend` | "找东西是find，记住 i 在中间——fin-d" |
| replace参数顺序 | `replace("新","旧")` 写反了 | "先写旧的，再写新的——就像先脱旧衣服再穿新衣服" |
| 点号遗漏 | `s.replace(...)` 写成 `sreplace(...)` | "方法前面要有点号——s点replace" |
| len当作方法 | `s.len()` 写成带括号加点的 | "len是函数，不是方法——没有点号！直接 `len(s)`" |
| int/str类型混用 | `find(123)` 而不是 `find("123")` | "find要找的是字符串，要用引号括起来" |

### 7.3 时间弹性策略

| 如果时间紧（孩子进度慢） | 如果时间松（孩子进度快） |
|---|---|
| 砍掉实操③综合创意，改为全班一起补全代码 | 增加"字符串加密挑战"：用replace实现简单凯撒密码 |
| startswith/endswith精简为各一个例子 | 让学生自己设计"颜色名分析"创意 |
| 故意犯错只做①和③，其余口头讲解 | 增加"找不同"环节：两个相似方法对比（replace vs find） |
| 小测缩减为Q1+Q2+Q4 | 增加Q8："怎么判断字符串是否以'.py'结尾？" |

---

## 八、教具准备清单

| 教具 | 数量 | 用途 | 备注 |
|------|------|------|------|
| 电脑（已装Python+turtle） | 每人1台 | 上机敲代码 | 提前确认turtle和中文支持 |
| 投影仪/大屏幕 | 1台 | 教师演示+展示代码 | 核心教具 |
| 白板/黑板+马克笔 | 1套 | 板书索引图和对比表 | 多色更佳 |
| 第10节_字符串方法下.py | 每人1份 | 教学代码文件 | 提前放在桌面 |
| 课堂练习册_第10节_字符串方法下.md | 每人1份 | 课堂3道实操题 | 提前打印 |
| 课后练习卡_第10节_字符串方法下.md | 每人1份 | 课后作业 | 下课发放 |
| 计时器 | 1个 | 控制环节节奏 | 手机计时即可 |

---

## 九、身体锚点速查卡（老师口袋版）

| 锚点编号 | 身体动作 | 对应概念 | 触发时机 |
|---------|---------|---------|---------|
| 锚点1 | 用手指在空气中划行，像翻书找字 | `find()` 找位置 | 每次提到 find |
| 锚点2 | 两手做交换动作（左手递出旧物，右手接过新物） | `replace()` 换内容 | 每次提到 replace |
| 锚点3 | 用手指计数（1、2、3……） | `count()` 数次数 | 每次提到 count |
| 锚点4 | 手指指向开头 + 点头 | `startswith()` | 每次提到 startswith |
| 锚点5 | 手指指向结尾 + 点头 | `endswith()` | 每次提到 endswith |
| 锚点6 | 两手张开比划"这么长" | `len()` 长度 | 每次提到 len |
| 锚点7 | 双手交叉画X | "字符串不可变" | 强调不可变性时 |

---

## 十、课堂问题预案

| 可能出现的情况 | 应对方案 |
|-------------|---------|
| 孩子问"为什么计算机从0开始数？" | "因为内存地址从0开始——就像小区的楼栋号从1栋开始一样，这是计算机世界的规则。你只需要记住：第0位=第一个。" |
| 孩子问"find('e')返回1，但'hello'里e明明是第2个字母？" | "我们人类数数从1开始，但计算机从0开始。一个是人类的习惯，一个是计算机的习惯。" |
| 孩子问"为什么字符串不能改？" | "就像你在纸上写了一个字——写上去就不能改了。要改只能写在新的纸上。字符串在内存里也是一样的，不能改，只能创建新的。" |
| replace第三个参数（次数）不理解 | "就像你改错别字——如果说'只改第一个'，那就是改一次。如果说'全部改'，那就是不写次数参数。" |
| 孩子分不清len和count | 画图：`len("banana")` 把6个字母都圈起来，`count("a")` 只圈a。一个数总数，一个数指定的 |
| startswith大小写问题 | "计算机是'脸盲'——大写A和小写a它觉得是两个不同的东西。所以 'Hello'.startswith('he') 是False。" |
| 孩子问"find找不到为什么是-1不报错？" | "因为-1是一个特殊数字，表示'没找到'。这样你可以在代码里判断——如果返回-1，说明没有；如果返回其他数字，就是找到了。" |
| 孩子写 `s.len()` | "len是函数，不是方法。方法前面有点号（s.find()），函数前面没有——你直接写 `len(s)` 就行。" |
| 学得快的孩子问"有没有从右边找的find？" | "有！`rfind()` 从右边开始找。还有 `index()` 和 `find()` 类似，但找不到会报错。" |
| 下课前还有孩子没做完实操 | 留作课后练习。优先保证前两个实操做完——这是核心内容 |

---

> **设计说明**：本教案遵循"先方法概念、后代码演示、再综合应用"的三段式教学。五大方法按"定位→替换→统计→判断→度量"的逻辑链依次展开，每个方法4-5分钟精讲。综合演示环节用 turtle 颜色列表串联全部方法，让学生看到字符串方法在真实场景中的组合使用。记忆钩子"find()找位置 replace()换内容 count()数次数"反复出现，形成长期记忆锚点。
