> **GESP等级：二级 | 考级考点：GESP Python 二级**

# 06第07节4 — f-string格式化输出

**关联GESP考点：GESP #27b（格式化输出）、GESP #27c（对齐与精度控制）**

---

## 一、教学目标

### 知识目标
1. 理解 f-string 的基本语法：`f"{变量}"`
2. 掌握 `{value:.2f}` 控制小数位数的格式
3. 掌握 `{value:d}` 整数格式的用法
4. 掌握 `{value:>10}` / `{value:<10}` / `{value:^10}` 三种对齐方式
5. 理解格式化符号与冒号配合的规则

### 能力目标
1. 能用 f-string 将浮点数格式化为指定位数小数
2. 能用 `:d` 确保输出整数类型
3. 能用对齐格式制作整齐的表格输出
4. 能组合多种格式控制符实现美观输出

### 情感目标
- 培养"精益求精"的输出美学——代码不仅要正确，还要好看
- 体验格式化输出带来的成就感，激发编程兴趣

---

## 二、教学重点与难点

| 类型 | 内容 |
|------|------|
| **重点** | `{value:.2f}` 小数位数控制；`{value:>10}` 三种对齐方式 |
| **难点** | 冒号后格式串的组合顺序；`.` 与 `d` 的互斥（`.2d` 不合法）；对齐宽度与填充 |
| **易错点** | `:.2f` 是四舍五入而非截断；`:d` 不能用于浮点数；`{ }` 花括号在 f-string 中需写为 `{{}}` 转义 |

---

## 三、教学过程

### 第一阶段：导入（00:00-10:00）

**主题：太多小数位了！—— 用格式说明书整理输出**

**问题情境（海龟坐标）：**
```python
import turtle
t = turtle.Turtle()
t.forward(120)
print(t.xcor())   # 输出：120.000000
```

**引导语：**
> 同学们，看这个 `120.000000`—— 后面跟了一堆零，看着不难受吗？
> 就像你写作业，字写得密密麻麻、歪歪扭扭，老师看着也难受。
> Python 里有一种"格式说明书"，就像写字用的格线本，能让输出变得整整齐齐！

**对比展示：**
```python
# 乱糟糟的版本
PI = 3.1415926535
print(f"{PI}")              # 3.1415926535

# 整整齐齐的版本  
print(f"{PI:.2f}")          # 3.14
print(f"{PI:.4f}")          # 3.1416  ← 还自动四舍五入！
```

> 这个 `:.2f` 就是告诉 Python："我要保留 2 位小数，后面的我不要了！"

**板书标题：**
```
f-string 格式说明书
{变量:格式控制符}
  │       └── 格式说明书
  └── 要格式化的变量
```

---

### 第二阶段：知识点讲解（10:00-30:00）

#### 知识点①：f-string 基础语法

```python
name = "小明"
age = 10
print(f"我叫{name}，今年{age}岁")
# 输出：我叫小明，今年10岁
```

**核心规则：** `f"..."` 字符串中，用 `{ }` 包裹变量名，Python 会自动替换成变量的值。

**转义花括号：** 如果真想输出 `{` 或 `}`，要写两个：
```python
value = 5
print(f"集合包含 {{ {value} }} 个元素")
# 输出：集合包含 { 5 } 个元素
```

#### 知识点②：`{value:.2f}` —— 控制小数位数

```python
score = 3.1415926535
print(f"{score:.2f}")     # 3.14   ← 保留2位小数
print(f"{score:.3f}")     # 3.142  ← 保留3位（四舍五入！）
print(f"{score:.1f}")     # 3.1    ← 保留1位
print(f"{score:.0f}")     # 3      ← 保留0位（取整）
```

**关键理解：** `.2f` 中的 `.2` 表示小数位数，`f` 表示浮点数格式。
- Python 会**四舍五入**（不是截断！）
- `f` 全称是 `float`（浮点数）

**表格记忆：**
| 格式 | 输入 3.14159 | 含义 |
|------|:-----------:|:----:|
| `:.1f` | `3.1` | 1位小数 |
| `:.2f` | `3.14` | 2位小数 |
| `:.3f` | `3.142` | 3位小数 |

#### 知识点③：`{value:d}` —— 整数格式

```python
num = 42
print(f"{num:d}")         # 42
print(f"{num:,d}")        # 42    ← 千位分隔符（大数用）
big = 1000000
print(f"{big:,d}")        # 1,000,000
```

**注意：** `:d` 只能用于整数，如果 value 是浮点数会报错！

```python
# print(f"{3.14:d}")      # ❌ 报错！ValueError
```

**:d 与 :.2f 的对比：**
| 格式 | 适用 | 示例 | 结果 |
|------|------|------|:----:|
| `:.2f` | 浮点数 | `{3.1415:.2f}` | `3.14` |
| `:d` | 整数 | `{42:d}` | `42` |
| `:,d` | 大整数 | `{1000000:,d}` | `1,000,000` |

#### 知识点④：`{value:>10}` —— 右对齐

```python
name = "小明"
print(f"|{name:>10}|")   # |        小明|  ← 右对齐，宽度10
```

**格式拆解：**
- `>` 表示右对齐（arrow 指向右 = 文字靠右）
- `10` 表示总宽度为 10 个字符
- 多余的空白自动补齐

**生活类比：** 就像你做值日排座位——
- `>10` = 往右站，留出左边空间
- 总宽度 = 这一排总共坐几个人

#### 知识点⑤：`{value:<10}` 和 `{value:^10}` —— 左对齐和居中对齐

```python
name = "小明"
print(f"|{name:<10}|")   # |小明        |  ← 左对齐
print(f"|{name:^10}|")   # |    小明    |  ← 居中对齐
```

**三种对齐记忆表：**

| 符号 | 含义 | 记忆口诀 | 示例 `"小明"`宽度8 |
|:----:|:----:|:--------:|:-----------------:|
| `<` | 左对齐 | 向左指 = 靠左 | `小明     ` |
| `>` | 右对齐 | 向右指 = 靠右 | `     小明` |
| `^` | 居中 | 尖尖在中间 | `  小明   ` |

**组合使用示例：**

```python
# 打印整齐的分数表
name = "小明"
chinese = 95
math = 88.5
english = 92.0

print(f"| {name:^6} | {chinese:>5} | {math:>5.1f} | {english:>5.1f} |")
# | 小明   |    95 |  88.5 |  92.0 |
```

---

### 第三阶段：演示（30:00-40:00）

#### 演示①：π 的格式化

```python
import math

print(f"π ≈ {math.pi}")          # π ≈ 3.141592653589793
print(f"π ≈ {math.pi:.2f}")      # π ≈ 3.14    ← 保留2位
print(f"π ≈ {math.pi:.4f}")      # π ≈ 3.1416  ← 保留4位（四舍五入）
print(f"π ≈ {math.pi:.1f}")      # π ≈ 3.1     ← 保留1位
print(f"π ≈ {math.pi:.0f}")      # π ≈ 3       ← 保留0位
```

让学生猜测每一步的结果，观察四舍五入的效果。

#### 演示②：多列对齐输出

```python
# 学生成绩表
print(f"{'姓名':>8} {'语文':>8} {'数学':>8} {'英语':>8}")
print(f"{'小明':>8} {95:>8} {88.5:>8.1f} {92:>8.1f}")
print(f"{'小红':>8} {92:>8} {96:>8} {89.5:>8.1f}")
print(f"{'小刚':>8} {80:>8} {76.5:>8.1f} {85:>8.1f}")
```

输出效果：
```
     姓名        语文        数学        英语
     小明         95       88.5       92.0
     小红         92         96       89.5
     小刚         80       76.5       85.0
```

**追问：** "如果我想让姓名居中对齐，数字右对齐，怎么改？"

#### 演示③：d 格式与 ,d 千位分隔

```python
population = 1411750000  # 中国人口
print(f"中国人口：{population}")         # 1411750000
print(f"中国人口：{population:,d}")      # 1,411,750,000  ← 多了逗号好读！
```

---

### 第四阶段：实操（40:00-55:00）

#### 实操①：格式配对填空

请将左边的格式字符串与右边的输出效果配对：

```python
score = 3.14159
```

| 格式 | 输出结果 | 配对（填字母） |
|------|:--------:|:-------------:|
| A. `{score:.1f}` | ① `3.14` | → ___ |
| B. `{score:.2f}` | ② `3.1` | → ___ |
| C. `{score:.3f}` | ③ `3` | → ___ |
| D. `{score:.0f}` | ④ `3.142` | → ___ |

**答案：** A→②, B→①, C→④, D→③

#### 实操②：补全 f-string 格式

补全代码，让输出变成注释指定的效果：

```python
# 题目1：输出 "价格：99.50元"
price = 99.5
print(f"价格：{______}元")   # → "价格：99.50元"
# 答案：price:.2f

# 题目2：输出 "|小林          |"（左对齐，宽度12）
name = "小林"
print(f"|{______}|")       # → "|小林          |"
# 答案：name:<12

# 题目3：输出 "|          小林|"（右对齐，宽度12）
print(f"|{______}|")       # → "|          小林|"
# 答案：name:>12

# 题目4：输出 "|    小林     |"（居中对齐，宽度12）
print(f"|{______}|")       # → "|    小林     |"
# 答案：name:^12

# 题目5：输出 "1,000,000"
big = 1000000
print(f"{______}")          # → "1,000,000"
# 答案：big:,d
```

#### 实操③：乌龟状态仪表盘（海龟坐标格式化）

```python
import turtle

t = turtle.Turtle()
t.speed(3)

# 向前走一段
t.forward(120)
t.right(45)
t.forward(80)

# 用格式化输出打印乌龟的当前位置
print("=" * 35)
print(f"| {'乌龟状态仪表盘':^27} |")
print("=" * 35)
print(f"| {'x坐标':>8} | {t.xcor():>10.2f} |")
print(f"| {'y坐标':>8} | {t.ycor():>10.2f} |")
print(f"| {'朝向角度':>8} | {t.heading():>10.1f} |")
print("=" * 35)
```

预期输出：
```
===================================
|          乌龟状态仪表盘          |
===================================
|     x坐标 |      120.00 |
|     y坐标 |       80.00 |
|   朝向角度 |       45.0 |
===================================
```

**拓展思考：** 如果把 `t.forward(120)` 改成 `t.forward(100/3)`，输出的 x 坐标会是什么？为什么？

---

### 第五阶段：小测与总结（55:00-60:00）

#### 小测题目

```
1. print(f"{3.14159:.2f}") 输出什么？
   A. 3.14    B. 3.14159    C. 3.1    D. 3.141
   答案：A（:.2f 保留2位小数，四舍五入）

2. print(f"|{'abc':>8}|") 输出什么？
   A. |abc     |    B. |     abc|    C. |  abc   |    D. |abc|
   答案：B（:>8 右对齐，宽度8）

3. print(f"{123:d}") 的输出是什么？
   A. 123     B. 123.0    C. "123"    D. 报错
   答案：A（:d 整数格式）

4. 以下哪个格式可以输出 "1,234,567"？
   A. {1234567:.2f}    B. {1234567:,d}
   C. {1234567:>10}    D. {1234567:d}
   答案：B（:,d 千位分隔符）

5. f-string 中如果想输出花括号 { 本身，应该怎么写？
   A. \{
   B. {
   C. {{
   D. \escape
   答案：C（{{ 转义为 {）
```

#### 课堂口诀

```
f-string 冒号后，格式说明书在手
:.2f 管小数，几位由你来定
:d 管整数，带个逗号更好读
:>10 右对齐，:<10 左对齐
:^10 居中间，整整齐齐真好看
```

#### 记忆钩子

> **"f-string冒号后控格式：:.2f管小数 :d管整数 :>10管对齐"**

---

## 四、板书设计

```
┌───────────────────────────────────────────────┐
│  f-string 格式说明书                          │
│  f"{变量:格式控制符}"                        │
│                                               │
│  小数位数：:.2f  →  3.14159 → 3.14          │
│            :.3f  →  3.14159 → 3.142  (四舍五入)│
│                                               │
│  整数格式：:d    →  42 → 42                 │
│           :,d   →  1000000 → 1,000,000     │
│                                               │
│  对齐方式：                                    │
│    :>10  右对齐    |     小明|                 │
│    :<10  左对齐    |小明      |                │
│    :^10  居中对齐   |   小明   |               │
│                                               │
│  组合使用：{name:>10} {score:.2f}            │
│                                               │
│  ⚠ :d 不能用于浮点数！                        │
│  ⚠ {{ 和 }} 转义花括号本身！                  │
└───────────────────────────────────────────────┘
```

## 五、课后反思

| 项目 | 记录 |
|------|------|
| 学生掌握较好的点 | |
| 学生易混淆的点 | |
| 需要补充练习的点 | |
| 下节调整建议 | |
