跳到主要内容

Python 文件操作

文件操作是处理数据的基础,本章将介绍如何读写文件。

文件打开和关闭

打开文件

# 基本语法
file = open("filename.txt", "r") # r 表示读取模式

# 常用模式
# r - 只读(默认)
# w - 只写(会覆盖原有内容)
# a - 追加
# rb - 二进制只读
# wb - 二进制只写
# ab - 二进制追加

# 关闭文件
file.close()

使用 with 语句(推荐)

自动管理文件资源:

with open("test.txt", "r") as file:
content = file.read()
# 文件会自动关闭

读取文件

read() - 读取全部内容

with open("test.txt", "r") as file:
content = file.read()
print(content)

readline() - 读取一行

with open("test.txt", "r") as file:
line1 = file.readline()
line2 = file.readline()
print(line1)
print(line2)

readlines() - 读取所有行

with open("test.txt", "r") as file:
lines = file.readlines()
for line in lines:
print(line.strip())

遍历文件对象

with open("test.txt", "r") as file:
for line in file:
print(line.strip())

指定字符数

with open("test.txt", "r") as file:
content = file.read(10) # 读取前10个字符
print(content)

写入文件

write() - 写入字符串

with open("test.txt", "w") as file:
file.write("Hello, World!\n")
file.write("第二行")

writelines() - 写入多行

lines = ["第一行\n", "第二行\n", "第三行\n"]
with open("test.txt", "w") as file:
file.writelines(lines)

追加模式

with open("test.txt", "a") as file:
file.write("追加的内容\n")

文件指针

tell() - 获取当前位置

with open("test.txt", "r") as file:
print(file.tell()) # 0
file.read(5)
print(file.tell()) # 5

seek() - 移动指针

with open("test.txt", "r") as file:
# seek(offset, whence)
# whence: 0=开头, 1=当前位置, 2=末尾

file.seek(0) # 移动到开头
file.seek(0, 2) # 移动到末尾
file.seek(5, 0) # 从开头移动5个字符

二进制文件

读取二进制文件

with open("image.jpg", "rb") as file:
data = file.read()
print(type(data)) # <class 'bytes'>

写入二进制文件

data = b"\x89PNG\r\n\x1a\n"
with open("image.png", "wb") as file:
file.write(data)

文件和目录操作

os 模块

import os

# 文件操作
os.remove("test.txt") # 删除文件
os.rename("old.txt", "new.txt") # 重命名
os.copy("src.txt", "dst.txt") # 复制(需要 shutil)

# 目录操作
os.mkdir("mydir") # 创建目录
os.rmdir("mydir") # 删除空目录
os.makedirs("a/b/c") # 创建多级目录
os.removedirs("a/b/c") # 删除多级目录

# 检查
os.path.exists("test.txt") # 检查是否存在
os.path.isfile("test.txt") # 是否是文件
os.path.isdir("mydir") # 是否是目录

# 获取信息
os.path.getsize("test.txt") # 文件大小
os.path.getmtime("test.txt") # 修改时间
os.getcwd() # 当前工作目录
os.listdir(".") # 列出目录内容

pathlib 模块(推荐)

from pathlib import Path

# 创建路径对象
p = Path("test.txt")

# 检查
p.exists() # 是否存在
p.is_file() # 是否是文件
p.is_dir() # 是否是目录

# 文件操作
p.read_text() # 读取文本
p.write_text("内容")# 写入文本
p.read_bytes() # 读取二进制
p.write_bytes(data) # 写入二进制

# 目录操作
p.mkdir() # 创建目录
p.rmdir() # 删除目录
p.iterdir() # 遍历目录

# 获取信息
p.name # 文件名
p.stem # 不带扩展名的文件名
p.suffix # 扩展名
p.parent # 父目录

# 路径操作
p / "subdir" # 拼接路径
p.resolve() # 转换为绝对路径

序列化

JSON 序列化

import json

# 写入 JSON
data = {"name": "张三", "age": 20, "city": "北京"}
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)

# 读取 JSON
with open("data.json", "r", encoding="utf-8") as f:
data = json.load(f)
print(data)

# 字符串与 JSON 互转
json_str = json.dumps(data, ensure_ascii=False)
data = json.loads(json_str)

pickle 序列化

import pickle

# 写入(序列化)
data = {"name": "张三", "scores": [90, 85, 95]}
with open("data.pkl", "wb") as f:
pickle.dump(data, f)

# 读取(反序列化)
with open("data.pkl", "rb") as f:
data = pickle.load(f)
print(data)

CSV 文件操作

读取 CSV

import csv

with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row)

写入 CSV

import csv

data = [
["姓名", "年龄", "城市"],
["张三", "20", "北京"],
["李四", "25", "上海"],
["王五", "22", "广州"]
]

with open("data.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerows(data)

使用字典读写 CSV

import csv

# 写入
with open("data.csv", "w", encoding="utf-8", newline="") as f:
fieldnames = ["name", "age", "city"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({"name": "张三", "age": "20", "city": "北京"})

# 读取
with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(row)

目录遍历

递归遍历

import os

def list_files(path):
for item in os.listdir(path):
full_path = os.path.join(path, item)
if os.path.isdir(full_path):
list_files(full_path) # 递归
else:
print(full_path)

list_files(".")

使用 pathlib

from pathlib import Path

def list_files(path):
for p in Path(path).rglob("*"):
if p.is_file():
print(p)

list_files(".")

小结

本章我们学习了:

  1. 文件的打开和关闭
  2. 读取文件的方法(read, readline, readlines)
  3. 写入文件的方法(write, writelines)
  4. 文件指针操作(tell, seek)
  5. 二进制文件操作
  6. os 和 pathlib 模块
  7. JSON 和 pickle 序列化
  8. CSV 文件操作
  9. 目录遍历

练习

  1. 实现一个文件复制函数
  2. 统计文本文件中每个字符出现的次数
  3. 实现一个日志记录器,将日志写入文件
  4. 批量重命名指定目录下的文件