Python文件操作

一、文件操作的核心概念

  1. 文件路径 :文件在电脑中的位置(如C:\Users\XXX\Desktop\test.txt(Windows)或/Users/XXX/Desktop/test.txt(Mac/Linux))
    • 绝对路径:从根目录开始的完整路径
    • 相对路径:相对于当前程序所在文件夹的路径(如./test.txt表示程序同文件夹下的 test.txt)
  2. 文件模式:打开文件的方式(读、写、追加、二进制等),后面会详细讲
  3. 文件句柄:打开文件后返回的 "操作对象",可以理解为 "文件的遥控器",所有操作都通过它完成
  4. 编码格式 :文件的字符编码(最常用的是utf-8,避免中文乱码)

二、文件操作的基本流程

无论哪种文件操作,核心流程都是:

打开文件(open) → 操作文件(读/写/修改) → 关闭文件(close)

重点:打开的文件必须关闭,否则会占用电脑内存,甚至导致文件损坏!

三、基础操作:打开与关闭文件

3.1 用open()函数打开文件

open()是 Python 内置的打开文件的函数,语法:

python 复制代码
文件句柄 = open(文件路径, 模式, encoding=编码格式)
参数 作用
文件路径 字符串类型,必填;可以是绝对路径或相对路径
模式 字符串类型,可选(默认是r);决定打开文件的方式
encoding 字符串类型,可选;指定文件编码(推荐utf-8,解决中文乱码)
常用文件模式
模式 含义 注意事项
r 只读模式(默认) 文件必须存在,否则报错
w 写入模式 文件不存在则创建,存在则清空原有内容
a 追加模式 文件不存在则创建,新内容追加到文件末尾
r+ 读写模式 文件必须存在,可读可写
w+ 写读模式 清空原有内容,可写可读
a+ 追加 + 读模式 新内容追加到末尾,可读可写
rb 二进制只读模式(如图片、视频、exe 文件) 不指定 encoding,按字节操作
wb 二进制写入模式 同上

3.2 用close()关闭文件

打开文件后,必须用close()关闭,示例:

python 复制代码
# 第一步:打开文件(桌面的test.txt,只读模式,utf-8编码)
# 注意:Windows路径中的\需要转义为\\,或用r前缀(原始字符串)
f = open(r"C:\Users\XXX\Desktop\test.txt", "r", encoding="utf-8")

# (这里可以加读/写操作)

# 第三步:关闭文件
f.close()

3.3 更安全的方式:with语句

手动close()容易忘记,Python 提供了with语句,自动关闭文件,即使代码出错也会关闭,语法:

python 复制代码
with open(文件路径, 模式, encoding=编码格式) as 文件句柄:
    # 缩进内:执行文件操作
    # 缩进结束:自动关闭文件
python 复制代码
# 用with打开文件,自动关闭
with open(r"C:\Users\XXX\Desktop\test.txt", "r", encoding="utf-8") as f:
    # 这里写操作代码
    content = f.read()  # 读取文件内容
    print(content)
# 缩进结束,文件已自动关闭,无需写f.close()

✅ 小白建议:所有文件操作优先用 with 语句,避免忘记关闭文件的坑!

四、文件读取操作

读取文件是获取文件内容的过程,有 4 种常用方法,覆盖所有场景:

4.1 读取全部内容:read()

语法:文件句柄.read(size)

  • size(可选):指定读取的字节数,不写则读取全部
  • 适合小文件(一次性读入内存)
python 复制代码
# 读取整个文件内容
with open("test.txt", "r", encoding="utf-8") as f:  # 相对路径(程序同文件夹)
    all_content = f.read()
    print("文件全部内容:")
    print(all_content)

4.2 按行读取:readline()

语法:文件句柄.readline()

  • 每次读取一行 内容(包括换行符\n
  • 适合大文件(逐行读,节省内存),可配合循环使用
python 复制代码
# 逐行读取文件
with open("test.txt", "r", encoding="utf-8") as f:
    # 读取第一行
    line1 = f.readline()
    print("第一行:", line1)  # 输出带换行符,所以print后会多一空行
    
    # 读取第二行
    line2 = f.readline()
    print("第二行:", line2.strip())  # strip()去掉换行符/空格
    
    # 读取第三行
    line3 = f.readline()
    print("第三行:", line3.strip())
    
    # 读取第四行(无内容,返回空字符串)
    line4 = f.readline()
    print("第四行:", repr(line4))  # repr显示空字符串

输出:

python 复制代码
第一行: Hello Python!

第二行: 我是文件操作的测试内容
第三行: 第3行
第四行: ''

4.3 读取所有行到列表:readlines()

语法:文件句柄.readlines()

  • 将文件的每一行作为列表的一个元素,返回列表
  • 适合需要对每行内容做批量处理的场景
python 复制代码
with open("test.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()
    print("所有行的列表:", lines)
    # 遍历列表,处理每行
    for i, line in enumerate(lines):  # enumerate获取行号+内容
        print(f"第{i+1}行:{line.strip()}")

输出:

python 复制代码
所有行的列表: ['Hello Python!\n', '我是文件操作的测试内容\n', '第3行']
第1行: Hello Python!
第2行: 我是文件操作的测试内容
第3行: 第3行

4.4 直接遍历文件句柄(最推荐的逐行读取方式)

语法:for line in 文件句柄:

  • 逐行读取,内存占用最少,适合超大文件(如 10G 的日志文件)
  • 代码最简洁
python 复制代码
# 遍历文件句柄,逐行读取(最优方式)
with open("test.txt", "r", encoding="utf-8") as f:
    for line_num, line in enumerate(f, start=1):  # start=1表示行号从1开始
        print(f"第{line_num}行内容:{line.strip()}")

输出和上面一致,但内存效率更高!

读取的常见问题与解决

  1. 中文乱码 :打开文件时指定encoding="utf-8"

  2. (如果还是乱码,试试gbk,Windows 记事本默认编码是 gbk)

    python 复制代码
    # 解决乱码:切换编码
    with open("test.txt", "r", encoding="gbk") as f:
        print(f.read())
  3. 文件不存在报错FileNotFoundError,检查路径是否正确,或先判断文件是否存在

五、文件写入操作

写入文件是将内容保存到文件的过程,核心模式:w(覆盖)、a(追加)。

5.1 覆盖写入:w模式

⚠️ 重点:w模式会清空文件原有内容,再写入新内容;如果文件不存在,会自动创建。

语法:文件句柄.write(内容)

  • 内容必须是字符串类型(数字需要转成 str)
  • write()返回写入的字符数

示例 1:写入简单内容

python 复制代码
# 覆盖写入(文件不存在则创建)
with open("write_test.txt", "w", encoding="utf-8") as f:
    # 写入字符串
    f.write("这是用w模式写入的内容\n")
    f.write("第二行内容\n")
    # 写入数字(需转字符串)
    f.write(str(123456))

执行后,write_test.txt内容:

python 复制代码
这是用w模式写入的内容
第二行内容
123456

示例 2:多次写入(覆盖原有内容)

python 复制代码
# 第一次写入
with open("write_test.txt", "w", encoding="utf-8") as f:
    f.write("第一次写入的内容")

# 第二次写入(覆盖第一次的内容)
with open("write_test.txt", "w", encoding="utf-8") as f:
    f.write("第二次写入的内容(覆盖了之前的)")

最终文件内容:第二次写入的内容(覆盖了之前的)

5.2 追加写入:a模式

a模式不会清空原有内容,新内容追加到文件末尾;文件不存在则创建。

python 复制代码
# 第一步:先写入初始内容
with open("append_test.txt", "w", encoding="utf-8") as f:
    f.write("初始内容\n")

# 第二步:追加内容(用a模式)
with open("append_test.txt", "a", encoding="utf-8") as f:
    f.write("追加的第一行\n")
    f.write("追加的第二行\n")

# 查看最终内容
with open("append_test.txt", "r", encoding="utf-8") as f:
    print(f.read())

输出:

复制代码
初始内容
追加的第一行
追加的第二行

5.3 写入多行:writelines()

如果有一个字符串列表,想把每个元素作为一行写入,用writelines()

python 复制代码
# 准备要写入的行列表
lines = [
    "第一行\n",  # 手动加换行符,否则会连在一起
    "第二行\n",
    "第三行"
]

with open("lines_test.txt", "w", encoding="utf-8") as f:
    f.writelines(lines)

文件内容:

复制代码
第一行
第二行
第三行

写入的注意事项

  1. 写入的内容必须是字符串 :数字、列表等需用str()转换
  2. 换行需要手动加\n:否则所有内容会写在一行
  3. w模式慎用:确认不需要保留原有内容时再用

六、文件的高级操作

6.1 检查文件 / 文件夹是否存在(避免报错)

os模块(Python 内置)检查路径是否存在,避免FileNotFoundError

python 复制代码
import os  # 导入os模块

# 1. 检查文件是否存在
file_path = "test.txt"
if os.path.exists(file_path):
    print(f"文件{file_path}存在")
else:
    print(f"文件{file_path}不存在")

# 2. 检查是否是文件(避免路径是文件夹)
if os.path.isfile(file_path):
    print(f"{file_path}是文件")

# 3. 检查是否是文件夹
folder_path = "./test_folder"
if os.path.isdir(folder_path):
    print(f"{folder_path}是文件夹")

6.2 文件重命名与删除

os模块实现文件重命名和删除:

python 复制代码
import os

# 1. 重命名文件(旧路径,新路径)
os.rename("old_name.txt", "new_name.txt")

# 2. 删除文件(谨慎使用!删除后无法恢复)
if os.path.exists("delete_me.txt"):  # 先检查是否存在
    os.remove("delete_me.txt")
    print("文件已删除")
else:
    print("文件不存在")

6.3 文件夹操作

python 复制代码
import os

# 1. 创建文件夹
folder_name = "new_folder"
if not os.path.exists(folder_name):
    os.mkdir(folder_name)  # 创建单层文件夹
    # os.makedirs("a/b/c")  # 创建多层文件夹(如a文件夹下的b,b下的c)

# 2. 删除文件夹(空文件夹)
if os.path.exists(folder_name):
    os.rmdir(folder_name)

# 3. 删除非空文件夹(需用shutil模块)
import shutil
shutil.rmtree("non_empty_folder")  # 谨慎使用!

6.4 二进制文件操作(图片 / 视频 / 音频)

操作图片、视频等二进制文件时,用rb/wb模式,不指定 encoding

python 复制代码
# 复制一张图片(二进制读取→二进制写入)
with open("original.jpg", "rb") as f_read:  # 二进制只读
    img_data = f_read.read()  # 读取二进制数据

with open("copy.jpg", "wb") as f_write:  # 二进制写入
    f_write.write(img_data)  # 写入二进制数据
print("图片复制完成")

6.5 文件指针操作(移动读取 / 写入位置)

文件打开后,有一个 "指针"(光标),默认在文件开头,读取 / 写入后指针会移动。用seek()手动移动指针:

python 复制代码
with open("test.txt", "r", encoding="utf-8") as f:
    # 读取前5个字符
    print(f.read(5))  # 输出:Hello
    # 指针现在在第5个字符位置
    # 移动指针到文件开头(0表示开头,2表示末尾)
    f.seek(0)
    # 再次读取全部内容
    print(f.read())  # 输出完整内容

七、实战案例

案例 1:统计文件的行数和字符数

python 复制代码
# 统计test.txt的行数、字符数(排除空格/换行)
file_path = "test.txt"
line_count = 0  # 行数
char_count = 0  # 字符数

with open(file_path, "r", encoding="utf-8") as f:
    for line in f:
        line_count += 1  # 每行计数+1
        # 去掉换行符、空格,统计有效字符
        clean_line = line.strip().replace(" ", "")
        char_count += len(clean_line)

print(f"文件总行数:{line_count}")
print(f"文件有效字符数:{char_count}")

案例 2:批量修改文件内容(替换指定字符串)

python 复制代码
# 将test.txt中的"Python"替换为"Java",保存到新文件
with open("test.txt", "r", encoding="utf-8") as f_read:
    with open("test_new.txt", "w", encoding="utf-8") as f_write:
        for line in f_read:
            # 替换字符串
            new_line = line.replace("Python", "Java")
            # 写入新文件
            f_write.write(new_line)
print("替换完成,新文件已保存")

案例 3:读取大文件(避免内存溢出)

python 复制代码
# 读取10G的超大日志文件,逐行处理(只打印包含"error"的行)
big_file_path = "big_log.txt"
error_count = 0

with open(big_file_path, "r", encoding="utf-8") as f:
    for line in f:  # 逐行读取,内存只存一行
        if "error" in line.lower():  # 忽略大小写
            print(f"错误行:{line.strip()}")
            error_count += 1

print(f"总共找到{error_count}个错误行")

八、常见错误与解决方案

错误类型 原因 解决方案
FileNotFoundError 文件路径错误 / 文件不存在 检查路径拼写;用os.path.exists()先判断
UnicodeDecodeError 编码格式不匹配(如文件是 gbk,用 utf-8 读) 切换 encoding(utf-8/gbk)
PermissionError 没有文件读写权限 / 文件被其他程序占用 关闭占用文件的程序;检查文件权限
IsADirectoryError 路径指向文件夹,却当作文件操作 检查路径是否是文件(os.path.isfile()

总结

  1. 核心流程 :文件操作的基础是打开→操作→关闭,优先用with语句自动关闭文件,避免内存泄漏;
  2. 核心模式 :读取用r,覆盖写入用w,追加写入用a,二进制文件用rb/wb
  3. 核心方法 :读取用read()(小文件)/for line in f(大文件),写入用write(),批量写入用writelines()
  4. 避坑要点 :写入内容必须是字符串,中文乱码指定encoding="utf-8"w模式会覆盖原有内容需慎用。

3.1 读取方法(文本文件)

方法 作用 适用场景
f.read() 一次性读取文件全部内容 小体积文本文件
f.readline() 逐行读取,单次仅读一行 逐行处理、大文件分步读取
f.readlines() 读取所有行,返回字符串列表 需批量处理每行内容
for line in f: 迭代逐行读取,内存占用极低 超大文本文件、日志文件

3.2 写入方法(文本文件)

方法 作用 注意事项
f.write(字符串) 写入单行内容 需手动加换行符\n,仅支持字符串
f.writelines(列表) 批量写入多行内容 列表元素需为字符串,换行需手动添加

3.3 文件/文件夹管理(os模块常用操作)

操作类型 核心语法 备注
判断路径是否存在 os.path.exists(路径) 判断文件/文件夹,返回布尔值
判断是否为文件 os.path.isfile(路径) 区分文件与文件夹
文件重命名 os.rename(旧名, 新名) 需保证原文件存在
删除文件 os.remove(文件路径) 删除后无法恢复,谨慎使用
创建文件夹 os.mkdir(文件夹名) os.makedirs(路径) 创建单层目录 可一次性创建多级目录,无需逐层级创建
删除空文件夹 os.rmdir(文件夹名) 仅支持删除空目录
相关推荐
小张贼嚣张2 小时前
数据分析全流程实战:Python(Pandas/Matplotlib/Numpy)+ MySQL(附可下载数据源+多图形绘制)
python·数据分析·pandas
努力的小白o(^▽^)o2 小时前
面向课堂考勤场景的桌面端人脸识别签到系统
python·人脸识别
myloveasuka2 小时前
C++进阶:利用作用域解析运算符 :: 突破多态与变量隐藏
开发语言·c++
OxyTheCrack2 小时前
【C++】详细拆解std::mutex的底层原理
linux·开发语言·c++·笔记
sa100272 小时前
淘宝商品详情 API 接口开发实战:item_detail 调用、参数与 Python 示例
linux·数据库·python
云栖梦泽3 小时前
易语言开发从入门到精通:进阶篇·网络爬虫与数据采集分析系统深度实战
开发语言
lsx2024063 小时前
XSLT `<sort>` 元素详解
开发语言
_olone3 小时前
牛客每日一题:显生之宙(Java)
java·开发语言·算法·牛客
Sirens.3 小时前
Java 包装类、泛型与类型擦除
java·开发语言·javac