🎯 本章你会学到:with open 的正确姿势、编码问题,以及不要吞异常。建议边读边敲,每节练习先自己做,再展开答案对照。
文件操作和异常处理经常一起出现:打开文件可能失败、数据可能不合法。Python 用 with 和 try / except 把这两件事都写得很短。
写文件再读回来
with open("numbers.txt", "w", encoding="utf-8") as f:
for i in range(1, 4):
f.write(f"{i * 10}\n")
with open("numbers.txt", encoding="utf-8") as f:
total = sum(int(line) for line in f)
print("sum:", total)运行结果
sum: 60
with open(...) as f:退出代码块时自动关闭文件,即使中间抛异常。- 文本文件建议显式写
encoding="utf-8",避免不同平台默认编码不一致导致的乱码。 - 逐行读用
for line in f(内存友好),一次性读用f.read()或f.read()后splitlines()。
异常:只捕获你能处理的那种
捕获具体异常
def safe_div(a, b):
try:
return a / b
except ZeroDivisionError:
return None
print(safe_div(10, 2))
print(safe_div(1, 0))
total = 0
invalid = 0
for item in ["10", "abc", "20"]:
try:
total += int(item)
except ValueError:
invalid += 1
print("sum:", total, "invalid:", invalid)运行结果
5.0
None
sum: 30 invalid: 1
| 写法 | 用途 |
|---|---|
| try / except ValueError | 只处理预料中的错误 |
| try / except (A, B) | 处理多种异常 |
| try / except ... as e | 取出异常对象(打印 e) |
| try / finally | 不管是否出错都要收尾 |
| raise ValueError("msg") | 主动抛出异常 |
| else / finally | 没出错时执行 / 一定执行 |
⚠️ 易错点 不要写裸的
except: 或 except Exception: pass——它会连键盘中断和真 bug 一起吞掉,出问题时你什么都看不到。⚠️ 易错点
int("abc")、float("x") 会抛 ValueError;处理外部输入时必须有这一层保护。✍️ 本节练习
6.1必做写文件再读回来
读入 n 行文字,写入文件 out.txt,再读回来输出行数与总字符数。
输入 第一行 n;接下来 n 行文字。
输出 两行:lines=、chars=。
样例输入
2
hello
world样例输出
lines=2
chars=10💡 提示 写用 f.write(line + "\n");读用 f.read().splitlines()。
✅ 查看参考答案与解析
n = int(input())
lines = [input() for _ in range(n)]
with open("out.txt", "w", encoding="utf-8") as f:
for line in lines:
f.write(line + "\n")
with open("out.txt", encoding="utf-8") as f:
content = f.read().splitlines()
print(f"lines={len(content)}")
print(f"chars={sum(len(line) for line in content)}")解析 splitlines() 会去掉行尾换行符,这样统计字符数不会把换行算进去。
6.2挑战成绩汇总(读标准输入)
从标准输入读入若干行「姓名 分数」直到结束,输出人数、平均分(2 位小数)和最高分学生姓名。
输入 若干行「姓名 分数」。
输出 三行:count=、avg=、top=。
样例输入
Ann 90
Bob 95
Cid 88样例输出
count=3
avg=91.00
top=Bob💡 提示 用 for line in sys.stdin 逐行读;格式不对的行直接跳过。
✅ 查看参考答案与解析
import sys
count = 0
total = 0
top_name = ""
top_score = -1
for line in sys.stdin:
parts = line.split()
if len(parts) != 2:
continue
name, score = parts[0], int(parts[1])
count += 1
total += score
if score > top_score:
top_score = score
top_name = name
if count:
print(f"count={count}")
print(f"avg={total / count:.2f}")
print(f"top={top_name}")解析 for line in sys.stdin 是 Python 读标准输入最省内存的方式;line.split() 同时处理空格和制表符。