Python 文件操作完全指南

小飞兽 Python 336 次阅读 2026-05-31

概述

Python 文件操作是每个 Python 开发者必备的基础技能,涵盖了从读取本地文本文件、处理 CSV/JSON 数据格式,到管理二进制文件(图片、音视频)等常见场景。Python 内置的 open() 函数和相关模块(os、shutil、pathlib)提供了完整文件操作能力,无需依赖第三方库即可完成大多数文件处理任务。

基础语法

Python 文件操作最核心的是 open() 函数,它接受文件路径、打开模式(mode)和编码(encoding)三个主要参数。打开模式决定了能做什么操作:r=只读,w=只写(覆盖),a=追加,r+=读写。文件对象支持两种使用方式——手动 close() 关闭,或者用 with 语句自动管理资源(推荐)。

    • r:只读模式,文件不存在会报错。
    • w:只写模式,文件存在则覆盖,不存在则创建。
    • a:追加模式,在文件末尾添加内容。
    • b:二进制模式,与 r/w/a 组合使用,如 rb、wb。
    • x:新建模式,文件存在则报错,适合创建新文件。

    pathlib 是 Python 3.4 引入的面向对象路径操作模块,用 Path 对象表示文件路径,比传统的 os.path 函数更直观易读。

    完整代码示例+注释

    import os
    import shutil
    import json
    from pathlib import Path
    

    === 基础文件读写 ===

    使用 with 语句自动管理文件资源(推荐)

    with open('example.txt', 'w', encoding='utf-8') as f: f.write('第一行:你好,世界! ') f.write('第二行:Python 文件操作演示 ')

    读取文件内容

    with open('example.txt', 'r', encoding='utf-8') as f: content = f.read() # 一次性读取全部 print(content)

    按行读取,适合大文件

    with open('example.txt', 'r', encoding='utf-8') as f: for line in f: # 迭代器方式,内存友好 print(line.rstrip())

    === JSON 文件操作 ===

    data = { 'name': '张三', 'age': 28, 'skills': ['Python', 'JavaScript', 'Docker'], 'experience': [ {'company': 'A公司', 'years': 2}, {'company': 'B公司', 'years': 3} ] }

    写入 JSON 文件(格式化输出)

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

    读取 JSON 文件

    with open('user.json', 'r', encoding='utf-8') as f: loaded = json.load(f) print(f"姓名: {loaded['name']}, 技能数: {len(loaded['skills'])}")

    === pathlib 面向对象操作(推荐) ===

    base = Path('/home/ubuntu/projects')

    检查路径是否存在

    if (base / 'README.md').exists(): print('README.md 已存在')

    创建目录( parents=True 递归创建,exist_ok=True 忽略已存在)

    (base / 'output' / 'logs').mkdir(parents=True, exist_ok=True)

    遍历目录下的所有 .py 文件

    for py_file in base.rglob('*.py'): # rglob 递归匹配 size = py_file.stat().st_size print(f"{py_file.relative_to(base)}: {size} bytes")

    === 文件复制、移动、删除 ===

    src = Path('source.txt') dst = Path('backup/source_backup.txt')

    if src.exists():
    shutil.copy2(src, dst) # copy2 保留元数据(修改时间等)
    print(f'已复制到 {dst}')

    移动/重命名

    shutil.move('old_name.txt', 'new_name.txt')

    删除文件(谨慎使用)

    Path('temp.txt').unlink() # 删除单个文件

    Path('temp_dir').rmdir() # 删除空目录

    === 二进制文件操作 ===

    读取图片并复制

    with open('photo.jpg', 'rb') as f: data = f.read()

    print(f'图片大小: {len(data) / 1024:.1f} KB')

    安全写入二进制

    with open('photo_copy.jpg', 'wb') as f: f.write(data)

    === 文件锁(多进程访问同一文件时) ===

    import fcntl

    with open('shared.txt', 'a') as f:
    fcntl.flock(f.fileno(), fcntl.LOCK_EX) # 加独占锁
    f.write('进程安全写入
    ')
    fcntl.flock(f.fileno(), fcntl.LOCK_UN) # 解锁

    运行效果

    执行上述代码,会依次创建 example.txt(包含两行文本)、user.json(格式化的 JSON 数据)、photo_copy.jpg(图片副本)。pathlib 的 rglob('*.py') 会递归查找所有 Python 文件并打印相对路径和大小。文件锁示例在多进程场景下确保同一时刻只有一个进程能写入 shared.txt,避免数据竞争导致的内容损坏。

    使用 with open() 管理文件资源是最佳实践,即使代码在读写过程中抛出异常,文件也会被正确关闭,不会造成资源泄漏。对于大文件处理(如日志分析、CSV 数据导入数据库),建议使用迭代器方式逐行读取,而非一次性 load 到内存。

    常见问题

    Q1:写入中文内容时出现编码错误
    Python 3 默认使用 UTF-8 编码,在 open() 时显式传入 encoding='utf-8' 即可。如果文件不是 UTF-8 编码(如 Windows 常见的 GBK),需要指定对应编码如 encoding='gbk'。遇到编码问题可以用 chardet 库自动检测文件编码。

    Q2:使用 shutil.rmtree 删除目录时如何避开只读文件
    shutil.rmtree 在遇到只读文件时会报错。解决方案是先遍历目录,将所有文件改为可写属性后再删除,或者使用 onerror 参数传入一个回调函数处理错误:shutil.rmtree(path, onerror=lambda fn, p, e: os.chmod(p, 0o777) or fn(p))。

    Q3:pathlib 的 Path 对象如何转换为字符串
    直接用 str() 转换:str(Path('/home/a.txt'))。如果要获取纯文件名用 Path.name,需要去掉扩展名用 Path.stem,获取父目录用 Path.parent。在需要路径字符串的地方(如 open()、os.path 函数),pathlib 通常可以自动转换。

    Q4:文件写入后立即读取为什么内容不完整
    这通常是缓冲区的缘故。写入的数据可能还在 Python 的缓冲区中,没有真正写到磁盘。调用 f.flush() 强制刷新缓冲区,或者用 with 语句结束时自动关闭文件。另一个可能是文件被多个进程或线程同时读写,需要加文件锁。

    延伸阅读

  • watchdog 库:监听文件系统变化,适合实现自动构建、热重载等工具。