读写文件、遍历目录、批量重命名……这些"脏活累活"正是 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} 个文件")
💡 学习建议:拿自己的下载目录跑一遍这个整理脚本(先复制一份再测),再试着加一个"按修改日期归档"的功能。文件操作是脚本语言最实用的领域,练熟就能省下大量手工时间。