读写文件、遍历目录、批量重命名……这些"脏活累活"正是 Python 脚本的拿手好戏。本文围绕 open() 与 pathlib 展开,讲清楚文件模式、编码问题、目录遍历三大主题,最后用一个批量整理脚本收尾。
1. 打开文件:模式总览
| 模式 | 含义 | 说明 |
|---|---|---|
| r | 只读 | 默认模式,文件不存在报错 |
| w | 写入 | 覆盖写,文件不存在则创建 |
| a | 追加 | 在末尾追加,不覆盖原有内容 |
| r+ | 读写 | 不截断文件,指针在开头 |
| x | 独占创建 | 文件已存在则报错,防止覆盖 |
| b / t | 二进制 / 文本 | 如 rb、wb,图片等用二进制 |
2. 读取文件:三种姿势
read() 一次读完、readline() 读一行、readlines() 读所有行。大文件务必用迭代逐行处理:
# 全部读入(适合小文件)
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()
print(f"共 {len(content)} 个字符")
# 逐行处理(适合大文件,内存友好)
with open("data.txt", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip 去掉行尾换行符
# 读所有行到列表
with open("data.txt", encoding="utf-8") as f:
lines = f.readlines()
print(f"共 {len(lines)} 行")
编码参数 encoding="utf-8" 一定要写,否则 Windows 上默认用 GBK,遇到中文会乱码或报错。
3. 写入与追加
# 覆盖写入
with open("out.txt", "w", encoding="utf-8") as f:
f.write("第一行\n")
f.writelines(["第二行\n", "第三行\n"])
# 追加写入:保留原有内容
with open("out.txt", "a", encoding="utf-8") as f:
f.write("追加的内容\n")
# 验证结果
with open("out.txt", encoding="utf-8") as f:
print(f.read())
with 语句会在代码块结束时自动关闭文件,即使中途抛出异常也不会泄漏文件句柄。
4. pathlib:现代目录操作
pathlib 是 Python 3.4+ 推荐的文件路径库,用对象方法代替字符串拼接,跨平台且不易出错:
from pathlib import Path
p = Path("articles")
print(p.exists())
print(p.is_dir())
print(p.name)
print(p.parent)
# 路径拼接与后缀操作
q = Path("data") / "backup" / "report.txt"
print(q.suffix)
print(q.stem)
print(q.with_suffix(".csv"))
5. 遍历目录:glob 与 rglob
from pathlib import Path
# 当前目录下的所有 .py 文件(不递归)
for f in Path(".").glob("*.py"):
print(f.name, f.stat().st_size, "字节")
# 递归查找所有 .md 文件
for f in Path(".").rglob("*.md"):
print(f)
# 列出目录下所有条目
for item in Path(".").iterdir():
kind = "目录" if item.is_dir() else "文件"
print(f"[{kind}] {item.name}")
6. 实战:批量整理下载目录
把散落在目录里的文件按扩展名归类到子文件夹——这是最经典的自动化脚本:
from pathlib import Path
src = Path("downloads")
if not src.exists():
src.mkdir() # 不存在则创建
# 预先建好几个分类目录
for folder in ["图片", "文档", "压缩包", "其他"]:
(src / folder).mkdir(exist_ok=True)
# 按扩展名分类移动
for f in src.iterdir():
if f.is_dir():
continue # 跳过目录本身
ext = f.suffix.lower()
if ext in (".jpg", ".png", ".gif"):
dest = src / "图片"
elif ext in (".pdf", ".docx", ".txt"):
dest = src / "文档"
elif ext in (".zip", ".tar", ".gz"):
dest = src / "压缩包"
else:
dest = src / "其他"
f.rename(dest / f.name)
print(f"移动 {f.name} → {dest.name}/")
# 统计整理结果
for folder in src.iterdir():
if folder.is_dir():
count = len(list(folder.iterdir()))
print(f"{folder.name}: {count} 个文件")
💡 学习建议:拿自己的下载目录跑一遍这个整理脚本(先复制一份再测),再试着加一个"按修改日期归档"的功能。文件操作是脚本语言最实用的领域,练熟就能省下大量手工时间。