当前位置:首页>python>Python零基础入门(十五):Python批量操作文件,os模块详解

Python零基础入门(十五):Python批量操作文件,os模块详解

  • 2026-10-11 06:57:33
Python零基础入门(十五):Python批量操作文件,os模块详解

上周五下午5点,领导甩过来一个文件夹:「这3000个PDF发票,明天前帮我转成Excel。」

我差点原地去世。

手动转?按每份2分钟算,不吃不喝干10个小时。用Python?5行代码,3分钟跑完。


os模块:文件操作的瑞士军刀

Python处理文件,绕不开os模块。它不花哨,但实打实能干活。

路径拼接、目录遍历、文件重命名——这些脏活累活,os模块全包了。

路径操作:别再用字符串拼接了

新手最爱犯的错:用 + 号拼路径。Windows用反斜杠,Mac用正斜杠,代码一换环境就炸。

os.path.join 自动处理分隔符,跨平台不会出错:

import os# 错误示范:字符串拼接path = "C:" + "\\Users" + "\\test" + "\\file.txt"# 正确做法:os.path.joinpath = os.path.join("C:", "Users", "test", "file.txt")print(path)  # C:Users\test\file.txt(Windows自动用反斜杠)

其他常用路径函数:

# 判断路径是否存在os.path.exists("/home/test/data")  # True/False# 获取文件扩展名os.path.splitext("report.pdf")  # ('report', '.pdf')# 获取文件名和目录os.path.basename("/home/test/report.pdf")  # 'report.pdf'os.path.dirname("/home/test/report.pdf")   # '/home/test'# 获取文件大小(字节)os.path.getsize("report.pdf")  # 102400

目录操作:遍历文件夹的三种姿势

拿到一个文件夹,第一件事就是看里面有什么。os模块提供了三个函数,各有适用场景。

os.listdir —— 只看一层:

# 获取目录下所有文件名(不递归)files = os.listdir("/data/invoices")print(files)  # ['inv001.pdf', 'inv002.pdf', 'inv003.xlsx', ...]

os.walk —— 递归遍历,拿到完整路径:

# os.walk返回(目录路径, 子目录列表, 文件列表)的元组for root, dirs, files in os.walk("/data/invoices"):    for file in files:        full_path = os.path.join(root, file)        print(full_path)# 输出:# /data/invoices/inv001.pdf# /data/invoices/2024/inv002.pdf# /data/invoices/2024/inv003.pdf

os.makedirs —— 一次性创建多层目录:

# 递归创建目录,exist_ok=True表示目录存在也不报错os.makedirs("/data/output/2024/invoices", exist_ok=True)

文件操作:重命名、删除、移动

文件操作三件套:改名、删掉、看信息。

# 重命名文件os.rename("old_name.txt", "new_name.txt")# 删除文件(不存在会报错,先判断)if os.path.exists("temp.txt"):    os.remove("temp.txt")# 获取文件信息(大小、修改时间等)stat = os.stat("report.pdf")print(f"大小: {stat.st_size} 字节")print(f"修改时间: {stat.st_mtime}")

批量处理实战:从遍历到筛选

光说不练假把式。来个真实场景:把/data/invoices目录下所有PDF文件的名称,从"发票_001.pdf"改成"INV_001.pdf"。

import os# 设定目录folder = "/data/invoices"# 遍历所有文件for filename in os.listdir(folder):    # 筛选:只要PDF,且以"发票_"开头    if filename.endswith(".pdf") and filename.startswith("发票_"):        # 构造新文件名        new_name = filename.replace("发票_", "INV_")        # 拼接完整路径        old_path = os.path.join(folder, filename)        new_path = os.path.join(folder, new_name)        # 重命名        os.rename(old_path, new_path)        print(f"重命名: {filename} -> {new_name}")print("批量重命名完成!")

这段代码干了三件事:遍历 → 筛选 → 重命名。核心逻辑就8行,但能处理上万个文件。


案例:批量PDF转Excel/文本

回到开头的需求:3000个PDF发票,转成Excel。

需要用到额外的库:pdfplumber(提取PDF表格数据)和 openpyxl(写Excel)。

先装依赖:

pip install pdfplumber openpyxl

完整代码:

import osimport pdfplumberfrom openpyxl import Workbookdef pdf_to_excel(pdf_path, excel_path):    """把一个PDF里的表格提取到Excel"""    wb = Workbook()    ws = wb.active    with pdfplumber.open(pdf_path) as pdf:        for page in pdf.pages:            tables = page.extract_tables()            for table in tables:                for row in table:                    ws.append(row)    wb.save(excel_path)# 批量处理source_dir = "/data/invoices"output_dir = "/data/invoices_excel"os.makedirs(output_dir, exist_ok=True)pdf_count = 0for filename in os.listdir(source_dir):    if filename.endswith(".pdf"):        pdf_path = os.path.join(source_dir, filename)        excel_name = filename.replace(".pdf", ".xlsx")        excel_path = os.path.join(output_dir, excel_name)        pdf_to_excel(pdf_path, excel_path)        pdf_count += 1        print(f"[{pdf_count}] 已转换: {filename}")print(f"\n全部完成!共处理 {pdf_count} 个文件")

跑完之后,output文件夹里整整齐齐躺着3000个xlsx文件。整个过程不到3分钟。


踩坑记录:这些坑我替你踩过了

坑1:路径分隔符

Windows用 \\,Mac/Linux用 /。直接拼字符串必翻车。

解决方案:永远用os.path.join,不要手动拼。

坑2:中文文件名乱码

Windows下os.listdir()返回的中文文件名可能是乱码,因为系统默认编码是gbk。

解决方案:

import sysimport os# Windows下设置编码if sys.platform == 'win32':    # 方法1:设置环境变量    os.environ['PYTHONIOENCODING'] = 'utf-8'    # 方法2:对文件名进行编码转换    for filename in os.listdir('.'):        if isinstance(filename, bytes):            filename = filename.decode('utf-8')

坑3:PermissionError

正在读写文件时,另一个程序(比如Excel)占用了文件,直接报错。

解决方案:加try-except,跳过出错的文件继续处理。

for filename in os.listdir(source_dir):    try:        # 你的处理逻辑        process_file(filename)    except PermissionError:        print(f"跳过被占用的文件: {filename}")        continue

彩蛋:pathlib,更Pythonic的写法

Python 3.4引入了pathlib模块,用面向对象的方式处理路径,比os.path更优雅。

from pathlib import Path# 创建路径对象folder = Path("/data/invoices")# 遍历所有PDF(比os.listdir更直观)for pdf_file in folder.glob("*.pdf"):    print(pdf_file.name)           # 文件名    print(pdf_file.suffix)         # 扩展名:.pdf    print(pdf_file.stem)           # 不带扩展名:report    # 重命名    new_name = pdf_file.stem.replace("发票", "INV") + ".pdf"    pdf_file.rename(folder / new_name)

pathlib的路径用 / 拼接,代码更清晰。新项目建议优先用pathlib,老代码维护用os也完全没问题。


写在最后

文件批量处理是Python最实用的技能之一。掌握os模块,能帮你省下大量重复劳动。

记住三个原则:

  • • 路径用os.path.join,别手动拼
  • • 遍历用os.walk,递归目录不遗漏
  • • 操作加try-except,异常不中断

留个问题: 你用Python批量处理文件时,遇到过最坑的问题是什么?评论区聊聊,点赞最高的我下期专门写解决方案。

最新文章

随机文章