文件操作

Python 提供了丰富的文件操作功能,可以轻松地读取和写入文件。

读取文件

# 方法1:使用 with 语句(推荐)
with open('example.txt', 'r', encoding='utf-8') as file:
    content = file.read()  # 读取整个文件
    print(content)

# 方法2:逐行读取
with open('example.txt', 'r', encoding='utf-8') as file:
    for line in file:
        print(line.strip())  # strip() 去除换行符

# 方法3:读取所有行到列表
with open('example.txt', 'r', encoding='utf-8') as file:
    lines = file.readlines()
    print(lines)

写入文件

# 写入文本(覆盖模式)
with open('output.txt', 'w', encoding='utf-8') as file:
    file.write("Hello, Python!\n")
    file.write("这是第二行\n")

# 追加模式
with open('output.txt', 'a', encoding='utf-8') as file:
    file.write("这是追加的内容\n")

# 写入多行
lines = ["第一行\n", "第二行\n", "第三行\n"]
with open('output.txt', 'w', encoding='utf-8') as file:
    file.writelines(lines)

JSON 文件处理

import json

# 写入 JSON 文件
data = {
    "name": "张三",
    "age": 25,
    "hobbies": ["阅读", "编程", "旅行"]
}

with open('data.json', 'w', encoding='utf-8') as file:
    json.dump(data, file, ensure_ascii=False, indent=2)

# 读取 JSON 文件
with open('data.json', 'r', encoding='utf-8') as file:
    loaded_data = json.load(file)
    print(loaded_data)
💡 提示:使用 with 语句可以自动关闭文件,避免资源泄漏。

目录操作

Python 提供了 os 和 pathlib 模块来操作文件系统,包括创建、删除、遍历目录等。

使用 pathlib(推荐)

from pathlib import Path

# 获取当前目录
current_dir = Path.cwd()
print(f"当前目录: {current_dir}")

# 创建目录
new_dir = Path("my_folder")
new_dir.mkdir(exist_ok=True)  # exist_ok=True 避免目录已存在时报错

# 创建嵌套目录
nested_dir = Path("parent/child/grandchild")
nested_dir.mkdir(parents=True, exist_ok=True)

# 检查路径是否存在
print(f"目录是否存在: {new_dir.exists()}")

# 检查是否是目录
print(f"是目录吗: {new_dir.is_dir()}")

# 遍历目录
for item in current_dir.iterdir():
    if item.is_file():
        print(f"文件: {item.name}")
    elif item.is_dir():
        print(f"目录: {item.name}")

# 获取所有 Python 文件
python_files = list(current_dir.glob("*.py"))
print(f"Python 文件: {[f.name for f in python_files]}")

# 删除目录(必须为空)
empty_dir = Path("empty_folder")
empty_dir.mkdir(exist_ok=True)
empty_dir.rmdir()  # 只能删除空目录

# 删除文件
file_to_delete = Path("test.txt")
if file_to_delete.exists():
    file_to_delete.unlink()

使用 os 模块

import os

# 获取当前目录
current_dir = os.getcwd()
print(f"当前目录: {current_dir}")

# 创建目录
os.makedirs("my_folder", exist_ok=True)

# 创建嵌套目录
os.makedirs("parent/child", exist_ok=True)

# 列出目录内容
items = os.listdir(current_dir)
print(f"目录内容: {items}")

# 检查路径是否存在
print(f"路径存在: {os.path.exists('my_folder')}")

# 检查是否是目录
print(f"是目录: {os.path.isdir('my_folder')}")

# 检查是否是文件
print(f"是文件: {os.path.isfile('test.txt')}")

# 获取文件大小
if os.path.exists("example.txt"):
    size = os.path.getsize("example.txt")
    print(f"文件大小: {size} 字节")

# 删除空目录
os.rmdir("empty_folder")

# 删除文件
if os.path.exists("test.txt"):
    os.remove("test.txt")

路径操作

from pathlib import Path
import os

# 使用 pathlib
path = Path("/home/user/documents/file.txt")
print(f"文件名: {path.name}")           # file.txt
print(f"扩展名: {path.suffix}")         # .txt
print(f"父目录: {path.parent}")         # /home/user/documents
print(f"绝对路径: {path.absolute()}")

# 拼接路径
new_path = Path("/home/user") / "documents" / "file.txt"
print(f"拼接路径: {new_path}")

# 使用 os
path = "/home/user/documents/file.txt"
print(f"目录名: {os.path.dirname(path)}")      # /home/user/documents
print(f"文件名: {os.path.basename(path)}")    # file.txt
print(f"分割路径: {os.path.split(path)}")

# 拼接路径
new_path = os.path.join("/home/user", "documents", "file.txt")
print(f"拼接路径: {new_path}")

遍历目录树

import os

# 遍历目录树
for root, dirs, files in os.walk("."):
    print(f"当前目录: {root}")
    print(f"子目录: {dirs}")
    print(f"文件: {files}")
    print("-" * 40)

# 使用 pathlib 递归遍历
from pathlib import Path
for path in Path(".").rglob("*.py"):
    print(f"Python 文件: {path}")
💡 提示:pathlib 是 Python 3.4+ 引入的模块,提供了更面向对象的方式来处理路径,推荐使用。

异常处理

异常处理可以让程序在遇到错误时优雅地处理,而不是直接崩溃。

基本异常处理

try:
    result = 10 / 0
except ZeroDivisionError:
    print("错误:不能除以零")

try:
    number = int(input("请输入一个数字:"))
    print(f"你输入的数字是:{number}")
except ValueError:
    print("错误:请输入有效的数字")
except Exception as e:
    print(f"发生了未知错误:{e}")

else 和 finally

try:
    file = open('example.txt', 'r')
    content = file.read()
except FileNotFoundError:
    print("文件不存在")
else:
    # 没有异常时执行
    print(f"文件内容:{content}")
finally:
    # 无论是否有异常都会执行
    print("操作完成")
    if 'file' in locals():
        file.close()

抛出异常

def calculate_age(birth_year):
    current_year = 2026
    age = current_year - birth_year
    
    if age < 0:
        raise ValueError("出生年份不能大于当前年份")
    
    return age

try:
    age = calculate_age(2030)
except ValueError as e:
    print(f"错误:{e}")

自定义异常

class InvalidAgeError(Exception):
    """自定义异常"""
    pass

def set_age(age):
    if age < 0 or age > 150:
        raise InvalidAgeError("年龄必须在 0 到 150 之间")
    return age

try:
    set_age(200)
except InvalidAgeError as e:
    print(f"捕获到自定义异常:{e}")

PyPDF2

PyPDF2 是一个纯 Python 编写的 PDF 工具库,可以读取、分割、合并和转换 PDF 文件。

安装

pip install PyPDF2

读取 PDF 信息

from PyPDF2 import PdfReader

# 读取 PDF 文件
reader = PdfReader('example.pdf')

# 获取页数
print(f"总页数: {len(reader.pages)}")

# 获取 PDF 信息
info = reader.metadata
print(f"标题: {info.get('/Title', '未知')}")
print(f"作者: {info.get('/Author', '未知')}")
print(f"创建者: {info.get('/Creator', '未知')}")

# 读取第一页
page = reader.pages[0]
print(f"第一页内容: {page.extract_text()}")

提取所有文本

from PyPDF2 import PdfReader

def extract_text_from_pdf(pdf_path):
    reader = PdfReader(pdf_path)
    text = ""

    for page in reader.pages:
        text += page.extract_text() + "\n"

    return text

# 提取文本
text = extract_text_from_pdf('example.pdf')
print(text)

# 保存到文本文件
with open('output.txt', 'w', encoding='utf-8') as f:
    f.write(text)

合并 PDF 文件

from PyPDF2 import PdfMerger

# 创建合并器
merger = PdfMerger()

# 添加 PDF 文件
merger.append('file1.pdf')
merger.append('file2.pdf')
merger.append('file3.pdf')

# 或者使用文件对象
with open('file4.pdf', 'rb') as f:
    merger.append(f)

# 保存合并后的 PDF
merger.write('merged.pdf')
merger.close()

分割 PDF 文件

from PyPDF2 import PdfReader, PdfWriter

# 读取 PDF
reader = PdfReader('example.pdf')

# 分割:提取前 3 页
writer = PdfWriter()
for i in range(3):
    writer.add_page(reader.pages[i])

# 保存
with open('first_3_pages.pdf', 'wb') as f:
    writer.write(f)

# 分割:提取特定页面
writer = PdfWriter()
writer.add_page(reader.pages[0])  # 第1页
writer.add_page(reader.pages[2])  # 第3页
writer.add_page(reader.pages[4])  # 第5页

with open('selected_pages.pdf', 'wb') as f:
    writer.write(f)

旋转 PDF 页面

from PyPDF2 import PdfReader, PdfWriter

# 读取 PDF
reader = PdfReader('example.pdf')
writer = PdfWriter()

# 旋转所有页面 90 度
for page in reader.pages:
    page.rotate(90)
    writer.add_page(page)

# 保存
with open('rotated.pdf', 'wb') as f:
    writer.write(f)

# 旋转特定页面
writer = PdfWriter()
for i, page in enumerate(reader.pages):
    if i == 0:  # 第一页旋转 180 度
        page.rotate(180)
    writer.add_page(page)

with open('rotated_first_page.pdf', 'wb') as f:
    writer.write(f)

加密和解密 PDF

from PyPDF2 import PdfReader, PdfWriter

# 加密 PDF
reader = PdfReader('example.pdf')
writer = PdfWriter()

for page in reader.pages:
    writer.add_page(page)

# 添加密码
writer.encrypt('user_password', owner_password='owner_password')

# 保存加密的 PDF
with open('encrypted.pdf', 'wb') as f:
    writer.write(f)

# 解密 PDF
reader = PdfReader('encrypted.pdf')
if reader.is_encrypted:
    reader.decrypt('user_password')

# 提取解密后的内容
page = reader.pages[0]
print(page.extract_text())

添加水印

from PyPDF2 import PdfReader, PdfWriter

# 读取 PDF 和水印
pdf_reader = PdfReader('example.pdf')
watermark_reader = PdfReader('watermark.pdf')

writer = PdfWriter()

# 为每一页添加水印
watermark_page = watermark_reader.pages[0]
for page in pdf_reader.pages:
    page.merge_page(watermark_page)
    writer.add_page(page)

# 保存
with open('watermarked.pdf', 'wb') as f:
    writer.write(f)
💡 提示:PyPDF2 适合处理简单的 PDF 操作,如合并、分割、提取文本等。对于复杂的 PDF 操作,可以考虑使用 pdfplumber 或 PyMuPDF。

python-docx

python-docx 是一个用于创建和修改 Microsoft Word (.docx) 文件的 Python 库。

安装

pip install python-docx

创建 Word 文档

from docx import Document
from docx.shared import Pt, RGBColor, Inches

# 创建文档
doc = Document()

# 添加标题
doc.add_heading('文档标题', level=0)
doc.add_heading('一级标题', level=1)
doc.add_heading('二级标题', level=2)

# 添加段落
paragraph = doc.add_paragraph('这是一个普通段落。')

# 添加带格式的段落
paragraph = doc.add_paragraph()
run = paragraph.add_run('这是粗体文本。')
run.bold = True

run = paragraph.add_run(' 这是斜体文本。')
run.italic = True

run = paragraph.add_run(' 这是下划线文本。')
run.underline = True

# 添加列表
doc.add_paragraph('无序列表项1', style='List Bullet')
doc.add_paragraph('无序列表项2', style='List Bullet')
doc.add_paragraph('有序列表项1', style='List Number')
doc.add_paragraph('有序列表项2', style='List Number')

# 保存文档
doc.save('example.docx')
print("文档已保存为 example.docx")

添加表格

from docx import Document

doc = Document()

# 添加表格
table = doc.add_table(rows=4, cols=3)
table.style = 'Table Grid'

# 设置表头
header_cells = table.rows[0].cells
header_cells[0].text = '姓名'
header_cells[1].text = '年龄'
header_cells[2].text = '城市'

# 填充数据
data = [
    ['张三', 25, '北京'],
    ['李四', 30, '上海'],
    ['王五', 28, '广州']
]

for i, row_data in enumerate(data):
    row = table.rows[i + 1]
    row.cells[0].text = row_data[0]
    row.cells[1].text = str(row_data[1])
    row.cells[2].text = row_data[2]

doc.save('table_example.docx')

添加图片

from docx import Document
from docx.shared import Inches

doc = Document()

# 添加段落
doc.add_paragraph('下面是一张图片:')

# 添加图片
doc.add_picture('image.png', width=Inches(4.0))

# 添加带标题的图片
doc.add_heading('图片标题', level=2)
doc.add_picture('image.png', width=Inches(3.0))
doc.add_paragraph('图片说明文字')

doc.save('image_example.docx')

设置页面格式

from docx import Document
from docx.shared import Pt, Inches

doc = Document()

# 设置页面边距
sections = doc.sections
for section in sections:
    section.top_margin = Inches(1)
    section.bottom_margin = Inches(1)
    section.left_margin = Inches(1.25)
    section.right_margin = Inches(1.25)

# 添加内容
doc.add_heading('页面格式示例', level=1)
doc.add_paragraph('这个文档有自定义的页面边距。')

doc.save('page_format.docx')

读取 Word 文档

from docx import Document

# 读取文档
doc = Document('example.docx')

# 读取所有段落
for para in doc.paragraphs:
    print(para.text)

# 读取所有表格
for table in doc.tables:
    for row in table.rows:
        for cell in row.cells:
            print(cell.text, end=' | ')
        print()

# 读取文档信息
print(f"段落数: {len(doc.paragraphs)}")
print(f"表格数: {len(doc.tables)}")

修改现有文档

from docx import Document

# 打开现有文档
doc = Document('example.docx')

# 修改段落
for para in doc.paragraphs:
    if '旧文本' in para.text:
        para.text = para.text.replace('旧文本', '新文本')

# 修改表格
for table in doc.tables:
    for row in table.rows:
        for cell in row.cells:
            if '旧值' in cell.text:
                cell.text = cell.text.replace('旧值', '新值')

# 保存修改后的文档
doc.save('modified_example.docx')
💡 提示:python-docx 适合创建和修改简单的 Word 文档,对于复杂的格式需求可能需要使用其他工具。

docxtpl

docxtpl 是一个基于 python-docx 的模板库,可以使用 Jinja2 模板语法批量生成 Word 文档。

安装

pip install docxtpl

基本使用

from docxtpl import DocxTemplate

# 加载模板
doc = DocxTemplate("template.docx")

# 准备数据
context = {
    'name': '张三',
    'age': 25,
    'city': '北京',
    'hobbies': ['阅读', '编程', '旅行']
}

# 渲染模板
doc.render(context)

# 保存文档
doc.save("output.docx")
print("文档已生成")

模板示例

# 在 Word 模板中使用以下语法:

# 简单变量
# {{ name }}

# 条件判断
# {% if age >= 18 %}
# 成年人
# {% else %}
# 未成年
# {% endif %}

# 循环
# {% for hobby in hobbies %}
# - {{ hobby }}
# {% endfor %}

# 表格
# | 姓名 | 年龄 | 城市 |
# |------|------|------|
# {% for person in persons %}
# | {{ person.name }} | {{ person.age }} | {{ person.city }} |
# {% endfor %}

批量生成文档

from docxtpl import DocxTemplate

# 加载模板
template = DocxTemplate("template.docx")

# 准备数据列表
data_list = [
    {'name': '张三', 'age': 25, 'city': '北京'},
    {'name': '李四', 'age': 30, 'city': '上海'},
    {'name': '王五', 'age': 28, 'city': '广州'}
]

# 批量生成文档
for i, data in enumerate(data_list):
    context = {'person': data}
    template.render(context)
    template.save(f"output_{i+1}.docx")
    print(f"已生成: output_{i+1}.docx")

使用图片

from docxtpl import DocxTemplate
from docx.shared import Inches

# 加载模板
doc = DocxTemplate("template.docx")

# 准备数据(包含图片)
context = {
    'name': '张三',
    'photo': 'photo.png'  # 图片路径
}

# 渲染模板
doc.render(context)

# 保存文档
doc.save("output_with_image.docx")

复杂模板

from docxtpl import DocxTemplate
from datetime import datetime

# 加载模板
doc = DocxTemplate("invoice_template.docx")

# 准备发票数据
context = {
    'invoice_number': 'INV-2026-001',
    'date': datetime.now().strftime('%Y-%m-%d'),
    'customer': {
        'name': '某某公司',
        'address': '北京市朝阳区',
        'phone': '010-12345678'
    },
    'items': [
        {'name': '产品A', 'quantity': 2, 'price': 100.00},
        {'name': '产品B', 'quantity': 1, 'price': 200.00},
        {'name': '产品C', 'quantity': 3, 'price': 50.00}
    ],
    'total': 450.00
}

# 渲染模板
doc.render(context)

# 保存发票
doc.save("invoice_2026_001.docx")
💡 提示:docxtpl 非常适合批量生成格式统一的文档,如合同、发票、报告等。

openpyxl

openpyxl 是一个用于读写 Excel 2010 xlsx/xlsm/xltx/xltm 文件的 Python 库。

安装

pip install openpyxl

创建 Excel 文件

from openpyxl import Workbook

# 创建工作簿
wb = Workbook()

# 获取活动工作表
ws = wb.active
ws.title = "Sheet1"

# 写入数据
ws['A1'] = '姓名'
ws['B1'] = '年龄'
ws['C1'] = '城市'

# 写入多行数据
data = [
    ['张三', 25, '北京'],
    ['李四', 30, '上海'],
    ['王五', 28, '广州'],
    ['赵六', 32, '深圳']
]

for row in data:
    ws.append(row)

# 保存文件
wb.save('example.xlsx')
print("Excel 文件已保存")

读取 Excel 文件

from openpyxl import load_workbook

# 加载工作簿
wb = load_workbook('example.xlsx')

# 获取工作表
ws = wb.active

# 读取所有数据
for row in ws.iter_rows(values_only=True):
    print(row)

# 读取特定范围
for row in ws['A1:C4']:
    for cell in row:
        print(cell.value, end=' ')
    print()

# 获取工作表信息
print(f"工作表名: {ws.title}")
print(f"最大行数: {ws.max_row}")
print(f"最大列数: {ws.max_column}")

设置单元格样式

from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side

wb = Workbook()
ws = wb.active

# 设置标题样式
header_font = Font(name='Arial', size=12, bold=True, color='FFFFFF')
header_fill = PatternFill(start_color='4472C4', end_color='4472C4', fill_type='solid')
header_alignment = Alignment(horizontal='center', vertical='center')

# 设置边框
thin_border = Border(
    left=Side(style='thin'),
    right=Side(style='thin'),
    top=Side(style='thin'),
    bottom=Side(style='thin')
)

# 写入标题
headers = ['姓名', '年龄', '城市']
for col, header in enumerate(headers, 1):
    cell = ws.cell(row=1, column=col)
    cell.value = header
    cell.font = header_font
    cell.fill = header_fill
    cell.alignment = header_alignment
    cell.border = thin_border

# 写入数据并设置样式
data = [['张三', 25, '北京'], ['李四', 30, '上海']]
for row_idx, row_data in enumerate(data, 2):
    for col_idx, value in enumerate(row_data, 1):
        cell = ws.cell(row=row_idx, column=col_idx)
        cell.value = value
        cell.alignment = Alignment(horizontal='center')
        cell.border = thin_border

wb.save('styled_example.xlsx')

使用公式

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# 写入数据
ws['A1'] = '商品'
ws['B1'] = '单价'
ws['C1'] = '数量'
ws['D1'] = '总价'

data = [
    ['商品A', 10, 5],
    ['商品B', 20, 3],
    ['商品C', 15, 4]
]

for row in data:
    ws.append(row)

# 添加公式
for row in range(2, 5):
    ws[f'D{row}'] = f'=B{row}*C{row}'

# 添加总计
ws['A5'] = '总计'
ws['D5'] = '=SUM(D2:D4)'

wb.save('formula_example.xlsx')

操作多个工作表

from openpyxl import Workbook

wb = Workbook()

# 删除默认工作表
if 'Sheet' in wb.sheetnames:
    del wb['Sheet']

# 创建多个工作表
sheets = ['一月', '二月', '三月', '四月']
for sheet_name in sheets:
    wb.create_sheet(title=sheet_name)

# 在不同工作表中写入数据
for sheet in wb.worksheets:
    sheet['A1'] = '日期'
    sheet['B1'] = '销售额'

wb.save('multiple_sheets.xlsx')

图表

from openpyxl import Workbook
from openpyxl.chart import BarChart, Reference

wb = Workbook()
ws = wb.active

# 写入数据
data = [
    ['产品', '销售额'],
    ['A', 100],
    ['B', 150],
    ['C', 120],
    ['D', 180]
]

for row in data:
    ws.append(row)

# 创建图表
chart = BarChart()
chart.type = "col"
chart.style = 10
chart.title = "产品销售统计"
chart.y_axis.title = '销售额'
chart.x_axis.title = '产品'

# 设置数据范围
data_ref = Reference(ws, min_col=2, min_row=1, max_row=5, max_col=2)
cats_ref = Reference(ws, min_col=1, min_row=2, max_row=5)
chart.add_data(data_ref, titles_from_data=True)
chart.set_categories(cats_ref)

# 添加图表到工作表
ws.add_chart(chart, "E2")

wb.save('chart_example.xlsx')

合并单元格

from openpyxl import Workbook
from openpyxl.styles import Alignment

wb = Workbook()
ws = wb.active

# 合并单元格
ws.merge_cells('A1:D1')
ws['A1'] = '合并单元格示例'
ws['A1'].alignment = Alignment(horizontal='center', vertical='center')

# 合并多行
ws.merge_cells('A3:B5')
ws['A3'] = '多行合并'

wb.save('merged_cells.xlsx')
💡 提示:openpyxl 不支持 .xls 格式(旧版 Excel),如需处理 .xls 文件,可以使用 xlrd 和 xlwt 库。

python-pptx

python-pptx 是一个用于创建和修改 Microsoft PowerPoint (.pptx) 文件的 Python 库。

安装

pip install python-pptx

创建演示文稿

from pptx import Presentation

# 创建演示文稿
prs = Presentation()

# 添加标题幻灯片
slide_layout = prs.slide_layouts[0]  # 标题幻灯片布局
slide = prs.slides.add_slide(slide_layout)

title = slide.shapes.title
subtitle = slide.placeholders[1]

title.text = "演示文稿标题"
subtitle.text = "副标题"

# 保存
prs.save('presentation.pptx')
print("演示文稿已保存")

添加内容幻灯片

from pptx import Presentation

prs = Presentation()

# 添加内容幻灯片
slide_layout = prs.slide_layouts[1]  # 标题和内容布局
slide = prs.slides.add_slide(slide_layout)

# 设置标题
title = slide.shapes.title
title.text = "内容标题"

# 添加文本内容
content = slide.placeholders[1]
text_frame = content.text_frame
text_frame.text = "第一段文本"

# 添加更多段落
p = text_frame.add_paragraph()
p.text = "第二段文本"
p.level = 1

p = text_frame.add_paragraph()
p.text = "第三段文本"
p.level = 2

prs.save('content_slide.pptx')

添加图片

from pptx import Presentation
from pptx.util import Inches

prs = Presentation()

# 添加空白幻灯片
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)

# 添加图片
left = top = Inches(1)
height = Inches(5)
pic = slide.shapes.add_picture('image.png', left, top, height=height)

# 调整图片大小
pic = slide.shapes.add_picture('image2.png', Inches(5), Inches(1), width=Inches(3))

prs.save('image_slide.pptx')

添加表格

from pptx import Presentation
from pptx.util import Inches

prs = Presentation()

# 添加空白幻灯片
slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(slide_layout)

# 添加表格
rows, cols = 4, 3
left = top = Inches(1)
width = Inches(8)
height = Inches(3)

table = slide.shapes.add_table(rows, cols, left, top, width, height).table

# 设置表头
table.cell(0, 0).text = '姓名'
table.cell(0, 1).text = '年龄'
table.cell(0, 2).text = '城市'

# 填充数据
data = [
    ['张三', 25, '北京'],
    ['李四', 30, '上海'],
    ['王五', 28, '广州']
]

for i, row_data in enumerate(data, 1):
    for j, value in enumerate(row_data):
        table.cell(i, j).text = str(value)

prs.save('table_slide.pptx')

添加形状

from pptx import Presentation
from pptx.util import Inches
from pptx.enum.shapes import MSO_SHAPE

prs = Presentation()

# 添加空白幻灯片
slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(slide_layout)

# 添加矩形
left = Inches(1)
top = Inches(1)
width = Inches(2)
height = Inches(1)
shape = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top, width, height)
shape.fill.solid()
shape.fill.fore_color.rgb = (0, 0, 255)  # 蓝色

# 添加圆形
left = Inches(4)
shape = slide.shapes.add_shape(MSO_SHAPE.OVAL, left, top, width, height)
shape.fill.solid()
shape.fill.fore_color.rgb = (255, 0, 0)  # 红色

# 添加文本框
left = Inches(1)
top = Inches(3)
width = Inches(6)
height = Inches(1)
textbox = slide.shapes.add_textbox(left, top, width, height)
text_frame = textbox.text_frame
text_frame.text = "这是一个文本框"

prs.save('shapes_slide.pptx')

设置幻灯片背景

from pptx import Presentation
from pptx.util import Inches

prs = Presentation()

# 添加幻灯片
slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(slide_layout)

# 设置背景颜色
background = slide.background
fill = background.fill
fill.solid()
fill.fore_color.rgb = (200, 200, 255)  # 浅蓝色

# 添加标题
left = top = Inches(1)
width = height = Inches(1)
title_box = slide.shapes.add_textbox(left, top, width, height)
title_frame = title_box.text_frame
title_frame.text = "带背景的幻灯片"

prs.save('background_slide.pptx')

修改现有演示文稿

from pptx import Presentation

# 打开现有演示文稿
prs = Presentation('presentation.pptx')

# 遍历所有幻灯片
for slide in prs.slides:
    # 遍历幻灯片中的所有形状
    for shape in slide.shapes:
        if hasattr(shape, "text"):
            print(f"文本: {shape.text}")
            # 修改文本
            if "旧文本" in shape.text:
                shape.text = shape.text.replace("旧文本", "新文本")

# 保存修改后的演示文稿
prs.save('modified_presentation.pptx')

批量生成幻灯片

from pptx import Presentation
from pptx.util import Inches

# 创建演示文稿
prs = Presentation()

# 数据
data = [
    {'title': '产品A', 'content': '产品A的介绍'},
    {'title': '产品B', 'content': '产品B的介绍'},
    {'title': '产品C', 'content': '产品C的介绍'}
]

# 批量创建幻灯片
for item in data:
    slide_layout = prs.slide_layouts[1]
    slide = prs.slides.add_slide(slide_layout)
    
    # 设置标题
    title = slide.shapes.title
    title.text = item['title']
    
    # 设置内容
    content = slide.placeholders[1]
    content.text = item['content']

prs.save('batch_slides.pptx')
print("批量幻灯片已生成")
💡 提示:python-pptx 适合创建自动化报告、批量生成演示文稿等场景。

difflib

difflib 是 Python 内置的模块,用于比较序列,生成差异报告,支持多种输出格式。

比较字符串

import difflib

text1 = "Hello, World!"
text2 = "Hello, Python!"

# 创建 SequenceMatcher
matcher = difflib.SequenceMatcher(None, text1, text2)

# 相似度
ratio = matcher.ratio()
print(f"相似度: {ratio:.2f}")

# 获取匹配块
for block in matcher.get_matching_blocks():
    print(f"匹配: text1[{block.a}:{block.a + block.size}] = text2[{block.b}:{block.b + block.size}]")

统一差异格式

import difflib

text1 = """Line 1
Line 2
Line 3
Line 4"""

text2 = """Line 1
Line 2 modified
Line 3
Line 4 added"""

# 生成差异
diff = difflib.unified_diff(
    text1.splitlines(keepends=True),
    text2.splitlines(keepends=True),
    fromfile='file1.txt',
    tofile='file2.txt',
    lineterm=''
)

print(''.join(diff))

上下文差异格式

import difflib

text1 = """Line 1
Line 2
Line 3
Line 4"""

text2 = """Line 1
Line 2 modified
Line 3
Line 4 added"""

# 生成上下文差异
diff = difflib.context_diff(
    text1.splitlines(keepends=True),
    text2.splitlines(keepends=True),
    fromfile='file1.txt',
    tofile='file2.txt'
)

print(''.join(diff))

HTML 差异格式

import difflib

text1 = "Hello, World!"
text2 = "Hello, Python!"

# 生成 HTML 差异
diff = difflib.HtmlDiff().make_table(
    text1.splitlines(),
    text2.splitlines(),
    fromdesc='Text 1',
    todesc='Text 2'
)

print(diff)

比较文件

import difflib

# 读取文件
with open('file1.txt', 'r') as f:
    text1 = f.readlines()

with open('file2.txt', 'r') as f:
    text2 = f.readlines()

# 生成差异
diff = difflib.unified_diff(text1, text2, fromfile='file1.txt', tofile='file2.txt')

# 输出差异
for line in diff:
    print(line, end='')

NDiff 格式

import difflib

text1 = "Hello, World!"
text2 = "Hello, Python!"

# 生成 NDiff 格式
diff = difflib.ndiff(text1.splitlines(), text2.splitlines())

for line in diff:
    print(line)

获取差异操作

import difflib

text1 = "Hello, World!"
text2 = "Hello, Python!"

# 获取操作码
matcher = difflib.SequenceMatcher(None, text1, text2)

for tag, i1, i2, j1, j2 in matcher.get_opcodes():
    print(f"{tag}: text1[{i1}:{i2}] -> text2[{j1}:{j2}]")
    if tag == 'replace':
        print(f"  替换: '{text1[i1:i2]}' -> '{text2[j1:j2]}'")
    elif tag == 'delete':
        print(f"  删除: '{text1[i1:i2]}'")
    elif tag == 'insert':
        print(f"  插入: '{text2[j1:j2]}'")
    elif tag == 'equal':
        print(f"  相等: '{text1[i1:i2]}'")
💡 提示:difflib 适合文本比较、版本控制、差异分析等场景。

filecmp

filecmp 是 Python 内置的模块,用于比较文件和目录。

比较文件

import filecmp

# 比较两个文件
result = filecmp.cmp('file1.txt', 'file2.txt')
print(f"文件是否相同: {result}")

# 浅比较(只比较文件属性)
result = filecmp.cmp('file1.txt', 'file2.txt', shallow=True)
print(f"文件属性是否相同: {result}")

比较目录

import filecmp

# 比较两个目录
result = filecmp.cmpfiles('dir1', 'dir2', ['file1.txt', 'file2.txt'])
print(f"匹配的文件: {result.match}")
print(f"不匹配的文件: {result.mismatch}")
print(f"错误的文件: {result.funny}")

# 比较整个目录
result = filecmp.dircmp('dir1', 'dir2')
print(f"相同的文件: {result.same_files}")
print(f"不同的文件: {result.diff_files}")
print(f"独有的文件: {result.left_only}, {result.right_only}")

详细目录比较

import filecmp

# 比较目录并打印详细报告
result = filecmp.dircmp('dir1', 'dir2')

# 打印报告
result.report()

# 打印详细报告
result.report_full_closure()

# 打印部分报告
result.report_partial_closure()

检查文件是否存在

import filecmp
import os

# 检查文件是否存在
if os.path.exists('file1.txt') and os.path.exists('file2.txt'):
    result = filecmp.cmp('file1.txt', 'file2.txt')
    print(f"文件是否相同: {result}")
else:
    print("文件不存在")

递归比较目录

import filecmp
import os

def compare_dirs(dir1, dir2):
    """递归比较两个目录"""
    result = filecmp.dircmp(dir1, dir2)
    
    print(f"相同的文件: {result.same_files}")
    print(f"不同的文件: {result.diff_files}")
    print(f"dir1 独有: {result.left_only}")
    print(f"dir2 独有: {result.right_only}")
    
    # 递归比较子目录
    for common_dir in result.common_dirs:
        subdir1 = os.path.join(dir1, common_dir)
        subdir2 = os.path.join(dir2, common_dir)
        print(f"\n比较子目录: {common_dir}")
        compare_dirs(subdir1, subdir2)

# 使用
compare_dirs('dir1', 'dir2')
💡 提示:filecmp 适合文件同步、备份验证、目录比较等场景。