10Python编程:从入门到实践(第3版)

文件和异常

数据持久化

文件读写异常处理JSON

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第10章:文件和异常(Files and Exceptions)

一、导读

1.1 本章学习目标

第10章介绍Python的文件操作和异常处理。本章核心目标:

  • 掌握文件读写:open()、read()、write()
  • 学会使用with语句:自动管理资源
  • 掌握异常处理:try-except-else-finally
  • 学会使用JSON:数据序列化
  • 理解常见异常类型

1.2 为什么本章如此重要

文件操作和异常处理是编写实用程序的基础。正确使用with语句可以避免资源泄漏,良好的异常处理能让程序更加健壮。

1.3 核心问题引导

with语句的原理是什么?它解决了什么问题?

异常处理的层次结构是什么?

什么时候应该捕获异常,什么时候应该让异常传播?

JSON和pickle有什么区别?


二、核心概念详解

10.1 文件读写

python
# 读取文件
with open("example.txt", "r") as file:
    content = file.read()
    print(content)

# 逐行读取
with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())

# 读取为列表
with open("example.txt", "r") as file:
    lines = file.readlines()

# 写入文件
with open("output.txt", "w") as file:
    file.write("Hello, File!\n")
    file.write("Line 2\n")

# 追加模式
with open("output.txt", "a") as file:
    file.write("Appended line\n")

# 二进制模式
with open("image.png", "rb") as file:
    data = file.read()

10.2 异常处理

python
# 基本异常处理
try:
    number = int(input("Enter a number: "))
    result = 10 / number
    print(f"Result: {result}")
except ValueError:
    print("Invalid input! Please enter a number.")
except ZeroDivisionError:
    print("Cannot divide by zero!")
else:
    print("No exceptions occurred.")
finally:
    print("Execution completed.")

# 捕获所有异常
try:
    # 危险操作
    pass
except Exception as e:
    print(f"Error: {e}")

# 自定义异常
class ValidationError(Exception):
    def __init__(self, message, field=None):
        super().__init__(message)
        self.field = field

def validate_age(age):
    if age < 0 or age > 150:
        raise ValidationError("Invalid age", "age")

try:
    validate_age(-5)
except ValidationError as e:
    print(f"Validation error on {e.field}: {e}")

10.3 JSON数据

python
import json

# Python对象转JSON
data = {
    "name": "Alice",
    "age": 20,
    "courses": ["Math", "Physics"],
    "address": {"city": "Beijing", "zip": "100000"}
}

json_str = json.dumps(data, indent=2, ensure_ascii=False)
print(json_str)

# JSON转Python对象
parsed = json.loads(json_str)
print(parsed["name"])

# 文件操作
with open("data.json", "w") as f:
    json.dump(data, f, indent=2)

with open("data.json", "r") as f:
    loaded = json.load(f)
    print(loaded)

# JSON Lines格式
with open("data.jsonl", "w") as f:
    for item in data_list:
        f.write(json.dumps(item) + "\n")

10.4 文件路径

python
from pathlib import Path

# 创建路径对象
p = Path("documents/report.txt")

# 路径操作
print(p.parent)      # documents
print(p.name)        # report.txt
print(p.stem)        # report
print(p.suffix)      # .txt

# 绝对路径
abs_path = p.absolute()

# 检查文件
print(p.exists())
print(p.is_file())
print(p.is_dir())

# 遍历目录
for file in Path(".").glob("*.py"):
    print(file)

# 递归遍历
for file in Path(".").rglob("*.py"):
    print(file)

# 创建目录
Path("new_dir/sub_dir").mkdir(parents=True, exist_ok=True)

三、实战案例

3.1 配置管理器

python
import json
from pathlib import Path

class ConfigManager:
    def __init__(self, config_file="config.json"):
        self.config_file = Path(config_file)
        self.config = self._load()
    
    def _load(self):
        if self.config_file.exists():
            with open(self.config_file, "r") as f:
                return json.load(f)
        return {}
    
    def save(self):
        with open(self.config_file, "w") as f:
            json.dump(self.config, f, indent=2)
    
    def get(self, key, default=None):
        return self.config.get(key, default)
    
    def set(self, key, value):
        self.config[key] = value
        self.save()

# 使用
config = ConfigManager()
config.set("theme", "dark")
config.set("language", "zh")
print(config.get("theme"))

四、本章小结

第10章介绍了文件操作和异常处理:文件读写(open/read/write)、with语句、try-except异常处理、JSON序列化、pathlib路径操作。


五、思考与练习

思考题

with语句的__enter__和__exit__方法是什么?

异常链(raise from)如何使用?

如何自定义上下文管理器?

JSON不能序列化哪些Python对象?

编程练习

实现一个简单的日志系统,写入文件。

编写一个程序,读取CSV文件并统计信息。

实现一个带缓存的配置文件管理器。


10/11文件和异
0%