欢迎回来!🎉 这节课我们要学习如何与文件打交道——让程序可以保存数据和读取数据,就像给数据找个家!
前四节课我们学会了: - 变量和基本数据类型 - 条件判断和循环 - 列表和字典 - 函数(代码的魔法师)
这节课我们要学习如何让程序和文件交互,实现数据的持久化!
在之前的课程中,我们的数据都保存在内存里,程序一关闭,数据就消失了。
文件可以让数据永久保存在硬盘上,下次打开程序还能用!
✅ 保存游戏进度:下次接着玩
✅ 记录日志:程序运行时的信息
✅ 读取配置:程序的设置
✅ 处理数据:读取CSV、Excel等数据文件
✅ 生成报告:把结果保存成文件
# 打开文件的基本语法
file = open("文件名", "模式")
# 操作文件...
# 关闭文件
file.close()
| 模式 | 说明 |
|---|---|
r |
读取模式(默认),文件必须存在 |
w |
写入模式,文件不存在则创建,存在则覆盖 |
a |
追加模式,文件不存在则创建,存在则在末尾追加 |
r+ |
读写模式,文件必须存在 |
w+ |
读写模式,文件不存在则创建,存在则覆盖 |
a+ |
读写模式,文件不存在则创建,存在则在末尾追加 |
# 打开一个文件用于读取
f = open("test.txt", "r")
# 操作文件...
f.close() # 记得关闭!
# 使用with语句,会自动关闭文件
with open("test.txt", "r") as f:
# 在这里操作文件
pass # pass表示什么都不做
# 文件已经自动关闭了,不用手动调用close()
为什么推荐with语句? - 自动关闭文件,不会忘记 - 更安全,即使出错也会关闭 - 代码更简洁
# 读取整个文件内容
with open("test.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# 逐行读取
with open("test.txt", "r", encoding="utf-8") as f:
line1 = f.readline()
line2 = f.readline()
print("第一行:", line1.strip()) # strip()去掉换行符
print("第二行:", line2.strip())
# 读取所有行到列表
with open("test.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(f"文件共有{len(lines)}行")
# 遍历每一行
for i, line in enumerate(lines, 1):
print(f"第{i}行: {line.strip()}")
# 直接用for循环遍历文件
with open("test.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip())
# 写入内容(会覆盖原有内容)
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Hello, World!\n")
f.write("这是第二行\n")
f.write("Python文件操作很简单!\n")
# 追加内容(不会覆盖原有内容)
with open("output.txt", "a", encoding="utf-8") as f:
f.write("这是追加的内容\n")
f.write("不会覆盖原来的内容\n")
# 写入多行内容
lines = [
"第一行\n",
"第二行\n",
"第三行\n"
]
with open("output.txt", "w", encoding="utf-8") as f:
f.writelines(lines)
import os
# 获取当前工作目录
current_dir = os.getcwd()
print("当前目录:", current_dir)
# 列出目录内容
files = os.listdir(".")
print("目录内容:", files)
# 创建目录
os.makedirs("data", exist_ok=True) # exist_ok=True表示如果存在就不报错
# 检查路径是否存在
print("'data'目录存在吗?", os.path.exists("data"))
# 检查是文件还是目录
print("是文件吗?", os.path.isfile("test.txt"))
print("是目录吗?", os.path.isdir("data"))
# 路径拼接
full_path = os.path.join("data", "test.txt")
print("完整路径:", full_path)
from pathlib import Path
# 创建Path对象
current_path = Path.cwd()
print("当前目录:", current_path)
# 列出目录内容
files = list(current_path.glob("*")) # *表示所有文件
print("目录内容:", files)
# 创建目录
data_dir = Path("data")
data_dir.mkdir(exist_ok=True)
# 检查路径
print("'data'目录存在吗?", data_dir.exists())
print("是文件吗?", data_dir.is_file())
print("是目录吗?", data_dir.is_dir())
# 路径拼接
file_path = data_dir / "test.txt" # 使用/操作符
print("完整路径:", file_path)
import csv
# 写入CSV文件
data = [
["姓名", "年龄", "城市"],
["小明", 18, "北京"],
["小红", 17, "上海"],
["小刚", 19, "广州"]
]
with open("students.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(data)
# 读取CSV文件
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row)
# 使用字典方式读写CSV
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['姓名']} - {row['年龄']}岁 - {row['城市']}")
import json
# 数据
student = {
"name": "小明",
"age": 18,
"city": "北京",
"hobbies": ["读书", "游泳", "编程"],
"scores": {"数学": 90, "语文": 85, "英语": 88}
}
# 写入JSON文件
with open("student.json", "w", encoding="utf-8") as f:
json.dump(student, f, ensure_ascii=False, indent=2)
# 读取JSON文件
with open("student.json", "r", encoding="utf-8") as f:
data = json.load(f)
print(data)
print(f"姓名: {data['name']}")
print(f"爱好: {data['hobbies']}")
print(f"数学成绩: {data['scores']['数学']}")
# 复制图片(二进制文件)
with open("original.jpg", "rb") as source: # rb表示读取二进制
with open("copy.jpg", "wb") as target: # wb表示写入二进制
target.write(source.read())
文件操作可能会出错,我们需要处理异常!
try:
with open("不存在的文件.txt", "r", encoding="utf-8") as f:
content = f.read()
except FileNotFoundError:
print("错误:文件不存在!")
except PermissionError:
print("错误:没有权限访问文件!")
except Exception as e:
print(f"发生未知错误:{e}")
else:
print("文件读取成功!")
finally:
print("无论成功或失败都会执行这里")
让我们创建一个实用的程序!
import json
from pathlib import Path
class GradeManager:
def __init__(self, data_file="grades.json"):
self.data_file = Path(data_file)
self.grades = self.load_grades()
def load_grades(self):
"""加载成绩数据"""
if self.data_file.exists():
with open(self.data_file, "r", encoding="utf-8") as f:
return json.load(f)
return {}
def save_grades(self):
"""保存成绩数据"""
with open(self.data_file, "w", encoding="utf-8") as f:
json.dump(self.grades, f, ensure_ascii=False, indent=2)
def add_student(self, name, scores):
"""添加学生"""
self.grades[name] = scores
self.save_grades()
print(f"已添加学生:{name}")
def update_student(self, name, scores):
"""更新学生成绩"""
if name in self.grades:
self.grades[name] = scores
self.save_grades()
print(f"已更新学生:{name}")
else:
print(f"学生{name}不存在!")
def get_student(self, name):
"""获取学生信息"""
if name in self.grades:
return self.grades[name]
return None
def list_all(self):
"""列出所有学生"""
print("\n=== 所有学生成绩 ===")
for name, scores in self.grades.items():
avg_score = sum(scores.values()) / len(scores)
print(f"{name}: {scores}, 平均分: {avg_score:.1f}")
def get_average(self, subject):
"""计算某门课的平均分"""
scores = []
for student_scores in self.grades.values():
if subject in student_scores:
scores.append(student_scores[subject])
if scores:
return sum(scores) / len(scores)
return None
# 使用成绩管理系统
manager = GradeManager()
# 添加学生
manager.add_student("小明", {"数学": 90, "语文": 85, "英语": 88})
manager.add_student("小红", {"数学": 95, "语文": 92, "英语": 90})
manager.add_student("小刚", {"数学": 85, "语文": 80, "英语": 82})
# 列出所有学生
manager.list_all()
# 计算数学平均分
math_avg = manager.get_average("数学")
print(f"\n数学平均分: {math_avg:.1f}")
# 查询某个学生
xiaoming = manager.get_student("小明")
print(f"\n小明的成绩: {xiaoming}")
import datetime
from pathlib import Path
class Logger:
def __init__(self, log_dir="logs"):
self.log_dir = Path(log_dir)
self.log_dir.mkdir(exist_ok=True)
def get_log_file(self):
"""获取今天的日志文件名"""
today = datetime.date.today().strftime("%Y-%m-%d")
return self.log_dir / f"{today}.log"
def log(self, level, message):
"""记录日志"""
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_line = f"[{timestamp}] [{level}] {message}\n"
with open(self.get_log_file(), "a", encoding="utf-8") as f:
f.write(log_line)
print(log_line.strip())
def info(self, message):
"""记录信息"""
self.log("INFO", message)
def warning(self, message):
"""记录警告"""
self.log("WARNING", message)
def error(self, message):
"""记录错误"""
self.log("ERROR", message)
def debug(self, message):
"""记录调试信息"""
self.log("DEBUG", message)
# 使用日志系统
logger = Logger()
logger.info("程序启动")
logger.warning("这是一个警告信息")
logger.error("发生了一个错误")
logger.debug("调试信息")
logger.info("程序结束")
今天我们学会了:
✅ 文件操作的重要性:数据持久化
✅ 打开和关闭文件:open()和with语句
✅ 读取文件:read()、readline()、readlines()
✅ 写入文件:write()、writelines()
✅ 目录操作:os模块和pathlib模块
✅ 处理不同文件类型:CSV、JSON、二进制文件
✅ 异常处理:让程序更健壮
下节课预告:我们会学习模块和包,如何组织代码和使用别人写好的库!
继续加油!你已经掌握了Python编程的核心技能!💪