Python文件操作与异常处理(六)¶
章节概述¶
文件操作和异常处理是Python编程中不可或缺的部分。本章将介绍如何读写文件、处理异常以及使用上下文管理器。
学习目标¶
- 掌握文件的打开、读取、写入和关闭
- 理解异常处理机制
- 学会使用with语句和上下文管理器
- 了解常见异常类型和处理方法
(一)文件操作¶
文件的打开和关闭¶
# 打开文件
file = open("example.txt", "r", encoding="utf-8")
# 读取内容
content = file.read()
# 关闭文件
file.close()
文件打开模式¶
| 模式 | 说明 |
|---|---|
| 'r' | 只读模式(默认) |
| 'w' | 写入模式(覆盖) |
| 'a' | 追加模式 |
| 'x' | 创建模式(文件已存在则报错) |
| 'b' | 二进制模式 |
| '+' | 读写模式 |
读取文件¶
# 方法1:使用with语句(推荐)
with open("example.txt", "r", encoding="utf-8") as f:
content = f.read() # 读取全部内容
# 方法2:逐行读取
with open("example.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip()去除换行符
# 方法3:读取所有行到列表
with open("example.txt", "r", encoding="utf-8") as f:
lines = f.readlines() # 返回列表
# 方法4:逐行读取(内存友好)
with open("example.txt", "r", encoding="utf-8") as f:
while True:
line = f.readline()
if not line:
break
print(line.strip())
写入文件¶
# 写入字符串
with open("output.txt", "w", encoding="utf-8") as f:
f.write("第一行\n")
f.write("第二行\n")
# 写入多行
lines = ["行1\n", "行2\n", "行3\n"]
with open("output.txt", "w", encoding="utf-8") as f:
f.writelines(lines)
# 追加内容
with open("output.txt", "a", encoding="utf-8") as f:
f.write("追加的内容\n")
文件指针操作¶
with open("example.txt", "r", encoding="utf-8") as f:
print(f.tell()) # 0(当前位置)
content1 = f.read(10) # 读取前10个字符
print(f.tell()) # 10
f.seek(0) # 回到文件开头
print(f.tell()) # 0
实例分析¶
实例1:复制文件
def copy_file(source, destination):
"""复制文件"""
try:
with open(source, "r", encoding="utf-8") as src:
content = src.read()
with open(destination, "w", encoding="utf-8") as dst:
dst.write(content)
print(f"文件复制成功:{source} -> {destination}")
except FileNotFoundError:
print(f"源文件不存在:{source}")
except Exception as e:
print(f"复制失败:{e}")
# 使用
copy_file("input.txt", "output.txt")
实例2:统计文件内容
def count_file_stats(filename):
"""统计文件的行数、单词数、字符数"""
with open(filename, "r", encoding="utf-8") as f:
content = f.read()
lines = content.splitlines()
words = content.split()
chars = len(content)
return {
"行数": len(lines),
"单词数": len(words),
"字符数": chars
}
# 使用
stats = count_file_stats("example.txt")
print(f"行数:{stats['行数']}")
print(f"单词数:{stats['单词数']}")
print(f"字符数:{stats['字符数']}")
(二)异常处理¶
异常的概念¶
异常是程序运行时发生的错误,如果不处理会导致程序崩溃。
try-except语句¶
# 基本语法
try:
# 可能出错的代码
result = 10 / 0
except ZeroDivisionError:
# 处理特定异常
print("除数不能为零!")
# 捕获多种异常
try:
x = int(input("输入数字:"))
result = 10 / x
except ValueError:
print("输入的不是数字!")
except ZeroDivisionError:
print("除数不能为零!")
# 同时处理多种异常
try:
x = int(input("输入数字:"))
result = 10 / x
except (ValueError, ZeroDivisionError) as e:
print(f"发生错误:{e}")
# 捕获所有异常
try:
risky_code()
except Exception as e:
print(f"发生错误:{e}")
try-except-else-finally¶
try:
# 可能出错的代码
f = open("example.txt", "r")
content = f.read()
except FileNotFoundError:
print("文件不存在!")
except PermissionError:
print("没有权限读取文件!")
else:
# 没有异常时执行
print("文件读取成功!")
finally:
# 无论是否有异常都执行
print("执行清理操作...")
自定义异常¶
class InsufficientFundsError(Exception):
"""余额不足异常"""
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(f"余额不足:当前{balance}元,需要{amount}元")
class BankAccount:
def __init__(self, balance=0):
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise InsufficientFundsError(self.balance, amount)
self.balance -= amount
return self.balance
# 使用
account = BankAccount(100)
try:
account.withdraw(150)
except InsufficientFundsError as e:
print(e) # 余额不足:当前100元,需要150元
常见异常类型¶
| 异常类型 | 说明 |
|---|---|
| ValueError | 值错误 |
| TypeError | 类型错误 |
| FileNotFoundError | 文件不存在 |
| IndexError | 索引超出范围 |
| KeyError | 键不存在 |
| ZeroDivisionError | 除以零 |
| AttributeError | 属性错误 |
| ImportError | 导入错误 |
(三)上下文管理器¶
with语句的原理¶
class FileManager:
"""文件管理器上下文管理器"""
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
"""进入with语句时调用"""
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
"""退出with语句时调用"""
if self.file:
self.file.close()
# 返回False表示不抑制异常
return False
# 使用
with FileManager("example.txt", "r") as f:
content = f.read()
使用contextlib简化¶
from contextlib import contextmanager
@contextmanager
def managed_resource(name):
"""上下文管理器装饰器"""
print(f"获取资源:{name}")
try:
yield name # yield的值作为as的值
except Exception as e:
print(f"处理异常:{e}")
finally:
print(f"释放资源:{name}")
# 使用
with managed_resource("数据库连接") as resource:
print(f"使用资源:{resource}")
# 可以在这里处理业务逻辑
# 输出:
# 获取资源:数据库连接
# 使用资源:数据库连接
# 释放资源:数据库连接
实战练习¶
练习1:日志记录器¶
import datetime
class Logger:
"""简单日志记录器"""
def __init__(self, filename):
self.filename = filename
def log(self, level, message):
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] [{level}] {message}\n"
with open(self.filename, "a", encoding="utf-8") as f:
f.write(log_entry)
def info(self, message):
self.log("INFO", message)
def error(self, message):
self.log("ERROR", message)
def warning(self, message):
self.log("WARNING", message)
# 使用
logger = Logger("app.log")
logger.info("程序启动")
logger.warning("内存使用率高")
logger.error("数据库连接失败")
练习2:CSV文件处理¶
import csv
def write_csv(filename, headers, data):
"""写入CSV文件"""
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(headers)
writer.writerows(data)
def read_csv(filename):
"""读取CSV文件"""
with open(filename, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
return list(reader)
# 使用
headers = ["姓名", "年龄", "城市"]
data = [
["张三", 25, "北京"],
["李四", 30, "上海"],
["王五", 28, "广州"]
]
write_csv("students.csv", headers, data)
students = read_csv("students.csv")
for stu in students:
print(stu)
练习3:JSON配置文件处理¶
import json
def load_config(filename):
"""加载JSON配置文件"""
try:
with open(filename, "r", encoding="utf-8") as f:
return json.load(f)
except FileNotFoundError:
print(f"配置文件不存在:{filename}")
return {}
except json.JSONDecodeError as e:
print(f"JSON解析错误:{e}")
return {}
def save_config(filename, config):
"""保存配置到JSON文件"""
with open(filename, "w", encoding="utf-8") as f:
json.dump(config, f, indent=4, ensure_ascii=False)
# 使用
config = {
"database": {
"host": "localhost",
"port": 3306,
"name": "mydb"
},
"debug": True
}
save_config("config.json", config)
loaded_config = load_config("config.json")
print(loaded_config)
章节小结¶
本章介绍了Python文件操作和异常处理:
- 文件操作:掌握文件的打开、读取、写入和关闭
- 异常处理:理解try-except机制,处理程序错误
- 上下文管理器:使用with语句自动管理资源
- 自定义异常:创建符合业务需求的异常类
文件操作和异常处理是编写健壮程序的基础。
下一步¶
继续学习:常用标准库,学习Python常用的标准库模块。
重点提醒: - 始终使用with语句管理文件 - 捕获具体异常,不要捕获所有异常 - finally用于清理资源 - 上下文管理器让资源管理更优雅