Python 学习教程 - 第三篇:文件操作与异常处理
欢迎回到 Python 学习之旅!今天我们将学习如何处理文件和如何优雅地处理错误。
目录
文件操作基础
文件操作是编程中非常重要的技能,让我们能够处理数据持久化。
文件路径
import os
# 相对路径
file_path = "data.txt"
# 绝对路径
abs_path = "/home/user/data.txt"
# 获取当前工作目录
current_dir = os.getcwd()
print(f"当前目录:{current_dir}")
# 获取文件大小
file_size = os.path.getsize("data.txt")
print(f"文件大小:{file_size} 字节")
文件模式
| 模式 | 描述 |
|---|---|
r |
只读(默认) |
w |
写入(覆盖) |
a |
追加 |
r+ |
读写 |
rb |
二进制只读 |
wb |
二进制写入 |
文件读写
读取文件
读取整个文件
# 读取所有内容
with open("file.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
逐行读取
# 逐行读取
with open("file.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip() 去除行尾的换行符
读取指定行
# 读取前5行
with open("file.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
first_5_lines = lines[:5]
print(first_5_lines)
写入文件
写入内容
# 写入内容(覆盖)
with open("file.txt", "w", encoding="utf-8") as f:
f.write("第一行\n")
f.write("第二行\n")
f.write("第三行\n")
追加内容
# 追加内容
with open("file.txt", "a", encoding="utf-8") as f:
f.write("追加的内容\n")
f.write("更多追加内容\n")
写入多行
# 写入列表中的多行
lines = ["第一行", "第二行", "第三行"]
with open("file.txt", "w", encoding="utf-8") as f:
f.writelines(lines)
文件操作示例
# 创建并写入文件
data = [
"姓名,年龄,城市",
"张三,25,北京",
"李四,30,上海",
"王五,28,广州"
]
with open("students.csv", "w", encoding="utf-8") as f:
f.writelines("\n".join(data))
print("文件已创建!")
读取刚才创建的文件:
# 读取CSV文件
with open("students.csv", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
print(line.strip())
异常处理
程序运行时可能会遇到各种错误,异常处理让我们能够优雅地处理这些错误。
常见异常
| 异常 | 描述 |
|---|---|
FileNotFoundError |
文件不存在 |
PermissionError |
权限不足 |
ValueError |
值错误 |
TypeError |
类型错误 |
KeyError |
键不存在 |
IndexError |
索引越界 |
try-except 基础
try:
# 可能出错的代码
result = 10 / 0
except ZeroDivisionError:
print("除数不能为零!")
捕获多种异常
try:
# 尝试读取文件
with open("nonexistent.txt", "r", encoding="utf-8") as f:
content = f.read()
except FileNotFoundError:
print("文件不存在!")
except PermissionError:
print("没有权限读取文件!")
except Exception as e:
print(f"发生未知错误:{e}")
finally 块
try:
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("文件不存在")
finally:
# 无论是否出错都会执行
if 'file' in locals():
file.close()
print("清理工作完成")
else 块
try:
number = int(input("请输入一个数字:"))
except ValueError:
print("请输入有效的数字!")
else:
# 如果没有异常,执行这里
print(f"你输入的数字是:{number}")
print(f"平方是:{number ** 2}")
抛出异常
def check_age(age):
"""检查年龄是否合法"""
if age < 0:
raise ValueError("年龄不能为负数!")
elif age < 18:
raise PermissionError("你还未成年!")
else:
print("年龄合法!")
# 调用函数
try:
check_age(-5)
except ValueError as e:
print(f"错误:{e}")
except PermissionError as e:
print(f"错误:{e}")
模块与包
Python 的模块和包让我们能够组织代码,提高复用性。
导入模块
# 导入整个模块
import math
print(math.pi) # 3.141592653589793
print(math.sqrt(16)) # 4.0
# 导入特定函数
from math import sqrt, pi
print(sqrt(25)) # 5.0
print(pi) # 3.141592653589793
# 导入模块并取别名
import math as m
print(m.sqrt(9)) # 3.0
创建模块
创建一个新文件 mymodule.py:
# mymodule.py
def greet(name):
"""问候函数"""
print(f"你好,{name}!")
def add(a, b):
"""加法函数"""
return a + b
PI = 3.14159
在其他文件中使用:
import mymodule
mymodule.greet("张三")
result = mymodule.add(3, 5)
print(f"3 + 5 = {result}")
print(f"PI = {mymodule.PI}")
创建包
创建包结构:
mypackage/
├── __init__.py
├── module1.py
├── module2.py
└── subpackage/
├── __init__.py
└── submodule.py
__init__.py 文件:
# mypackage/__init__.py
from .module1 import greet
from .module2 import add
__all__ = ["greet", "add"]
使用包:
from mypackage import greet, add
greet("张三")
print(add(3, 5))
使用标准库
import random
import time
import datetime
# random
numbers = random.sample(range(1, 100), 5)
print(f"随机数:{numbers}")
# time
start_time = time.time()
time.sleep(1) # 休眠1秒
end_time = time.time()
print(f"耗时:{end_time - start_time:.2f}秒")
# datetime
now = datetime.datetime.now()
print(f"当前时间:{now.strftime('%Y-%m-%d %H:%M:%S')}")
综合练习
练习1:日志记录器
import datetime
import os
class Logger:
"""简单的日志记录器"""
def __init__(self, filename="app.log"):
self.filename = filename
def log(self, message, level="INFO"):
"""记录日志"""
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)
# 同时打印到控制台
print(log_entry.strip())
# 使用示例
logger = Logger()
logger.log("程序启动", "INFO")
logger.log("用户登录成功", "SUCCESS")
logger.log("数据库连接失败", "ERROR")
练习2:CSV 文件处理器
import csv
class CSVProcessor:
"""CSV 文件处理器"""
def __init__(self, filename):
self.filename = filename
def read_csv(self):
"""读取CSV文件"""
data = []
try:
with open(self.filename, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
data.append(row)
except FileNotFoundError:
print(f"文件 {self.filename} 不存在")
except Exception as e:
print(f"读取文件出错:{e}")
return data
def write_csv(self, data, filename=None):
"""写入CSV文件"""
if filename is None:
filename = self.filename
try:
with open(filename, "w", encoding="utf-8", newline="") as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
print(f"成功写入 {filename}")
except Exception as e:
print(f"写入文件出错:{e}")
# 使用示例
processor = CSVProcessor("students.csv")
# 读取
students = processor.read_csv()
for student in students:
print(student)
# 写入
new_data = [
{"姓名": "赵六", "年龄": 22, "城市": "深圳"},
{"姓名": "钱七", "年龄": 26, "城市": "杭州"}
]
processor.write_csv(new_data, "new_students.csv")
练习3:文件备份工具
import os
import shutil
from datetime import datetime
class FileBackup:
"""文件备份工具"""
def __init__(self, source_dir, backup_dir="backup"):
self.source_dir = source_dir
self.backup_dir = backup_dir
def backup_file(self, filename):
"""备份单个文件"""
try:
source_path = os.path.join(self.source_dir, filename)
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
backup_name = f"{filename}_{timestamp}.bak"
backup_path = os.path.join(self.backup_dir, backup_name)
shutil.copy2(source_path, backup_path)
print(f"已备份:{filename} -> {backup_name}")
return True
except Exception as e:
print(f"备份 {filename} 失败:{e}")
return False
def backup_all(self):
"""备份所有文件"""
if not os.path.exists(self.backup_dir):
os.makedirs(self.backup_dir)
files = os.listdir(self.source_dir)
success_count = 0
fail_count = 0
for filename in files:
if os.path.isfile(os.path.join(self.source_dir, filename)):
if self.backup_file(filename):
success_count += 1
else:
fail_count += 1
print(f"\n备份完成:成功 {success_count} 个,失败 {fail_count} 个")
# 使用示例
backup = FileBackup("documents")
backup.backup_all()
总结
今天我们学习了:
✅ 文件操作:读取、写入、追加、文件模式
✅ 异常处理:try-except-finally-else,捕获不同异常
✅ 模块与包:导入模块、创建模块和包、使用标准库
重要概念
- with 语句:自动管理文件资源,确保文件正确关闭
- 异常处理:让程序更加健壮,避免意外崩溃
- 模块化:将代码组织成模块,提高复用性
- 编码:文件操作时注意使用 UTF-8 编码
常用模块
os:操作系统相关操作sys:系统相关操作datetime:日期时间处理json:JSON 数据处理csv:CSV 文件处理
下次学习预告
下一篇我们将学习:
- 面向对象编程(OOP)
- 类和对象
- 继承、封装、多态
- 装饰器和生成器
继续学习!掌握这些技能后,你已经能写很多实用的程序了!