目录
[4.1 文件路径:找到你的 AI 资源](#4.1 文件路径:找到你的 AI 资源)
[4.1.1 获取和改变当前工作目录](#4.1.1 获取和改变当前工作目录)
[4.1.2 路径拼接(跨平台安全)](#4.1.2 路径拼接(跨平台安全))
[4.1.3 获取路径的各个部分](#4.1.3 获取路径的各个部分)
[4.2 读写文本文件:保存 API 响应和提示词](#4.2 读写文本文件:保存 API 响应和提示词)
[4.2.1 打开文件的模式](#4.2.1 打开文件的模式)
[4.2.2 写入文本文件](#4.2.2 写入文本文件)
[4.2.3 读取文本文件](#4.2.3 读取文本文件)
[4.2.4 AI 场景:记录 API 调用日志](#4.2.4 AI 场景:记录 API 调用日志)
[4.3 读写 JSON 文件:AI 配置和结构化数据](#4.3 读写 JSON 文件:AI 配置和结构化数据)
[4.3.1 写入 JSON 文件](#4.3.1 写入 JSON 文件)
[4.3.2 读取 JSON 文件](#4.3.2 读取 JSON 文件)
[4.3.3 AI 场景:批量保存对话历史](#4.3.3 AI 场景:批量保存对话历史)
[4.4 读写 CSV 文件:处理模型评估结果](#4.4 读写 CSV 文件:处理模型评估结果)
[4.4.1 使用 Python 内置的 csv 模块](#4.4.1 使用 Python 内置的 csv 模块)
[4.4.2 AI 场景:保存不同温度下的模型表现](#4.4.2 AI 场景:保存不同温度下的模型表现)
[4.5 文件与目录操作:管理模型文件、日志等](#4.5 文件与目录操作:管理模型文件、日志等)
[4.5.1 检查文件/目录是否存在](#4.5.1 检查文件/目录是否存在)
[4.5.2 创建目录](#4.5.2 创建目录)
[4.5.3 列出目录内容](#4.5.3 列出目录内容)
[4.5.4 重命名、移动、删除文件](#4.5.4 重命名、移动、删除文件)
[4.5.5 AI 场景:自动整理实验日志](#4.5.5 AI 场景:自动整理实验日志)
[4.6 使用 pathlib:更现代化的路径操作(推荐)](#4.6 使用 pathlib:更现代化的路径操作(推荐))
[4.6.1 创建路径](#4.6.1 创建路径)
[4.6.2 读写文件](#4.6.2 读写文件)
[4.6.3 遍历目录](#4.6.3 遍历目录)
[4.6.4 AI 场景:批量加载提示词文件](#4.6.4 AI 场景:批量加载提示词文件)
[4.7 综合实战:AI 实验数据管理工具](#4.7 综合实战:AI 实验数据管理工具)
[4.8 本章小结](#4.8 本章小结)
在 AI 开发中,你经常需要读写文件:保存 API 密钥、缓存模型回复、记录对话日志、加载训练数据等。本章将学习如何用
Python操作文件和目录,让你的 AI 应用能够持久化存储数据。所有示例都围绕大模型场景展开。
4.1 文件路径:找到你的 AI 资源
操作文件的第一步是指定文件的位置。路径分为两种:
-
绝对路径 :从根目录开始的完整路径(如
C:\Users\name\data.txt或/home/name/data.txt)。 -
相对路径 :相对于当前工作目录的路径(如
data.txt或./logs/chat.json)。
4.1.1 获取和改变当前工作目录
python
current_dir = os.getcwd()
print(f"当前目录:{current_dir}")
# 改变工作目录
os.chdir("/path/to/your/project")
print(f"新目录:{os.getcwd()}")
4.1.2 路径拼接(跨平台安全)
不同操作系统的路径分隔符不同(Windows 用 \,Linux/macOS 用 /)。用 os.path.join 可以自动适配。
python
import os
# AI 项目中的典型路径结构
base_dir = "/home/tianpeng/my-ai-service"
data_dir = os.path.join(base_dir, "data", "prompts")
print(data_dir) # /home/user/ai_project/data/prompts
# 安全地拼接文件名
file_path = os.path.join(data_dir, "train.json")
print(file_path)
4.1.3 获取路径的各个部分
python
path = "/home/user/models/gpt-4/config.json"
dir_name = os.path.dirname(path) # /home/user/models/gpt-4
base_name = os.path.basename(path) # config.json
name, ext = os.path.splitext(base_name) # ('config', '.json')
os.path.dirname(path) 用于提取路径中的目录部分(即去掉最后一个斜杠后的文件名部分),os.path.basename(path) 则提取最后的文件名或目录名,而 os.path.splitext(base_name) 将文件名拆分为不含扩展名的主体和扩展名两部分(如 ('config', '.json'))。这三个函数常组合使用来解析文件路径的各个组成部分,方便后续操作。
4.2 读写文本文件:保存 API 响应和提示词
文本文件是最常见的存储格式,用于保存配置、日志、提示词等。
4.2.1 打开文件的模式
| 模式 | 含义 |
|---|---|
'r' |
只读(默认) |
'w' |
写入(会覆盖原有内容) |
'a' |
追加(在文件末尾添加) |
'x' |
创建新文件,如果已存在则报错 |
'r+' |
读写 |
加上 'b' 表示二进制模式(如 'rb')。
4.2.2 写入文本文件
open(file, mode, encoding) 是 Python 读写文件的核心函数:使用 "w" 模式会覆盖或新建 文件并写入内容(如示例中的 prompt.txt);使用 "a" 模式则在文件末尾追加 新内容而不覆盖原有数据。配合 with open(...) as f: 语句可以自动管理文件关闭,encoding="utf-8" 确保中文正常编码。
python
# 写入一个新的提示词文件
with open("prompt.txt", "w", encoding="utf-8") as f:
f.write("请用中文解释大语言模型的注意力机制。\n")
f.write("要求:通俗易懂,不超过200字。")
# 追加一条新的提示
with open("prompt.txt", "a", encoding="utf-8") as f:
f.write("\n\n另一个问题:什么是 Transformer?")
4.2.3 读取文本文件
open(file, "r", encoding="utf-8") 以只读模式打开文本文件。使用 f.read() 可以一次性读取整个文件内容为字符串,适合小文件;而使用 for line in f 逐行迭代则每次只加载一行到内存,适合处理大文件。两种方式都配合 with 语句确保文件自动关闭。
python
# 读取整个文件内容
with open("prompt.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# 逐行读取(适合大文件)
with open("prompt.txt", "r", encoding="utf-8") as f:
for line in f:
print("行:", line.strip())
💡
with语句 :自动管理文件打开和关闭,即使发生异常也会正确关闭文件。推荐总是使用with。
4.2.4 AI 场景:记录 API 调用日志
python
import datetime
def log_api_call(model, prompt, response, tokens_used):
with open("api_log.txt", "a", encoding="utf-8") as log:
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log.write(f"[{timestamp}] 模型: {model}\n")
log.write(f" 输入: {prompt[:50]}...\n")
log.write(f" 输出: {response[:50]}...\n")
log.write(f" Token: {tokens_used}\n\n")
# 模拟调用
log_api_call("gpt-4", "讲个笑话", "为什么程序员总分不清万圣节和圣诞节?", 120)
这个示例定义了一个 log_api_call 函数,它使用 open("api_log.txt", "a", encoding="utf-8") 以追加模式打开日志文件,确保每次调用不会覆盖已有记录。函数内部获取当前时间戳,并将模型名称、输入提示词前 50 个字符、模型回复前 50 个字符、消耗的 token 数格式化为多行文本写入文件。最后模拟调用该函数,演示了如何将 API 调用的关键信息持久化存储,便于后续审计或调试。
4.3 读写 JSON 文件:AI 配置和结构化数据
JSON 是非常常见的结构化数据格式,大模型的 API 请求和响应大多使用 JSON。
4.3.1 写入 JSON 文件
python
import json
# 模型配置数据
model_config = {
"model": "gpt-4",
"temperature": 0.7,
"max_tokens": 2048,
"top_p": 0.9,
"presence_penalty": 0.5
}
with open("config.json", "w", encoding="utf-8") as f:
json.dump(model_config, f, indent=4, ensure_ascii=False)
这段代码使用 json.dump() 将 Python 字典 model_config 写入 config.json 文件:indent=4 使输出的 JSON 具有缩进格式、易于阅读;ensure_ascii=False 确保中文字符正常显示(不会被转义为 \u 序列)。最终生成一个结构化、可读性好的配置文件,便于后续加载和使用。
-
indent=4:美化输出,带缩进。 -
ensure_ascii=False:允许中文字符正常显示。
4.3.2 读取 JSON 文件
python
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f)
print(config["model"]) # gpt-4
print(config["temperature"]) # 0.7
这段代码使用 open("config.json", "r", encoding="utf-8") 以只读模式打开 JSON 文件,然后通过 json.load(f) 将文件中的 JSON 字符串解析为 Python 字典对象(如示例中的 config)。之后可以直接通过键名访问配置项,例如 config["model"] 获取模型名称。这种方式常用于加载应用程序的配置文件。
4.3.3 AI 场景:批量保存对话历史
python
conversation = [
{"role": "system", "content": "你是一名AI助手"},
{"role": "user", "content": "什么是机器学习?"},
{"role": "assistant", "content": "机器学习是人工智能的一个分支..."}
]
with open("conversation.json", "w", encoding="utf-8") as f:
json.dump(conversation, f, indent=2, ensure_ascii=False)
# 读取并恢复对话
with open("conversation.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
for msg in loaded:
print(f"{msg['role']}: {msg['content'][:30]}...")
4.4 读写 CSV 文件:处理模型评估结果
CSV 是逗号分隔值的表格数据,适合存储批量测试结果。
4.4.1 使用 Python 内置的 csv 模块
python
import csv
# 写入 CSV
data = [
["model", "temperature", "accuracy", "latency_ms"],
["gpt-4", 0.7, 0.92, 450],
["gpt-3.5", 0.7, 0.87, 320],
["claude-3", 0.8, 0.94, 580]
]
with open("eval_results.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(data)
# 读取 CSV
with open("eval_results.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row)
这段代码演示了使用 Python 内置 csv 模块进行 CSV 文件的读写:写入时,调用 csv.writer 创建写入器,并通过 writer.writerows(data) 将表头和数据行一次性写入文件,其中 newline="" 参数用于避免在 Windows 系统上出现多余的空行;读取时,使用 csv.reader 创建读取器,然后遍历 reader 逐行获取 CSV 文件中的每行数据(以列表形式返回)。这种方式简洁高效,适合处理表格型数据。
4.4.2 AI 场景:保存不同温度下的模型表现
python
results = []
for temp in [0.1, 0.5, 1.0, 1.5]:
# 模拟一次评估
accuracy = 0.9 - abs(temp - 0.7) * 0.1 # 简单模拟
results.append({"temperature": temp, "accuracy": round(accuracy, 3)})
with open("temp_sensitivity.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["temperature", "accuracy"])
writer.writeheader()
writer.writerows(results)
print("结果已保存到 temp_sensitivity.csv")
这段代码模拟了不同温度参数对模型准确率的影响:首先遍历温度值列表 [0.1, 0.5, 1.0, 1.5],通过一个简单的线性公式(0.9 - abs(temp - 0.7) * 0.1)模拟准确率,并将每个温度及其对应的准确率以字典形式存入 results 列表。随后,使用 csv.DictWriter 并指定字段名 ["temperature", "accuracy"],通过 writer.writerows(results) 将字典列表一次性写入 temp_sensitivity.csv 文件中。这种方式可以自动将字典的键作为列头,方便记录和分析模型超参数对性能的影响。
4.5 文件与目录操作:管理模型文件、日志等
os 和 shutil 模块提供了丰富的文件和目录管理功能。
4.5.1 检查文件/目录是否存在
在 Python 中,检查文件或目录是否存在最常用的方法是 os.path.exists(path),它会返回 True 如果路径存在(无论是文件还是目录);若要区分类型,可使用 os.path.isfile(path) 判断是否为文件,或 os.path.isdir(path) 判断是否为目录。此外,pathlib 模块提供了更面向对象的写法:Path(path).exists()、Path(path).is_file()、Path(path).is_dir(),推荐在现代 Python 代码中使用。
python
import os
if os.path.exists("config.json"):
print("配置文件存在")
else:
print("配置文件不存在")
if os.path.isdir("logs"):
print("logs 目录存在")
else:
print("logs 目录不存在")
4.5.2 创建目录
在 Python 中创建目录主要使用 os.makedirs() 或 pathlib.Path.mkdir():os.makedirs(path, exist_ok=True) 可以递归 创建 中间缺失的目录,且 exist_ok=True 避免目录已存在时报错;而 pathlib.Path(path).mkdir(parents=True, exist_ok=True) 是面向对象风格,效果相同。如果需要仅创建最后一级目录(父目录必须存在),可使用 os.mkdir() 或 Path.mkdir(parents=False)。推荐使用 exist_ok=True / parents=True 组合来安全地创建目录。
python
# 创建单层目录
os.mkdir("outputs")
# 创建多层目录(如果父目录不存在也会创建)
os.makedirs("data/training/samples", exist_ok=True)
4.5.3 列出目录内容
在 Python 中,列出目录内容最常用的方法是 os.listdir(path),它返回目录下所有文件和子目录名称的列表(不含完整路径)。如果需要更高效地获取文件属性(如是否为目录),推荐使用 os.scandir(path),它返回 DirEntry 对象的迭代器,减少了系统调用次数。现代 Python 更推荐 pathlib.Path(path).iterdir(),它生成 Path 对象的生成器,可以方便地链式调用 .is_file()、.glob() 等方法。示例:[p for p in Path('.').iterdir() if p.is_file()] 可列出当前目录下的所有文件。
python
# 列出当前目录下的所有文件和子目录
items = os.listdir(".")
for item in items:
print(item)
# 只列出 .json 文件
for file in os.listdir("configs"):
if file.endswith(".json"):
print(f"配置文件: {file}")
4.5.4 重命名、移动、删除文件
在 Python 中,重命名或移动文件可以使用 os.rename(src, dst)(适用于同一文件系统内的重命名/移动),跨文件系统移动则推荐 shutil.move(src, dst);删除文件用 os.remove(file) 或 pathlib.Path(file).unlink(),删除空目录用 os.rmdir(dir),删除非空目录及所有内容用 shutil.rmtree(dir)。现代代码也常使用 pathlib.Path 的方法,如 Path(src).rename(dst) 重命名,Path(file).unlink() 删除文件。操作前最好先用 os.path.exists() 检查目标是否存在以避免异常。
python
import os
import shutil
# 重命名
os.rename("old_log.txt", "new_log.txt")
# 移动文件(如果目的地是目录,则移动进去)
shutil.move("data.csv", "backup/data_2025.csv")
# 删除文件
os.remove("temp.txt")
# 删除空目录
os.rmdir("empty_dir")
# 删除非空目录(谨慎!)
shutil.rmtree("old_experiments")
4.5.5 AI 场景:自动整理实验日志
python
import os
import shutil
from datetime import datetime
# 假设当前目录下有很多 .log 文件
log_files = [f for f in os.listdir(".") if f.endswith(".log")]
# 创建按日期分类的目录
today = datetime.now().strftime("%Y-%m-%d")
archive_dir = os.path.join("logs", today)
os.makedirs(archive_dir, exist_ok=True)
for log in log_files:
shutil.move(log, os.path.join(archive_dir, log))
print(f"已将 {len(log_files)} 个日志文件移动到 {archive_dir}")
4.6 使用 pathlib:更现代化的路径操作(推荐)
pathlib 模块从 Python 3.4 开始引入,提供了面向对象的路径操作方式,比 os.path 更直观。
4.6.1 创建路径
在 Python 中,pathlib 模块通过 Path 对象以面向对象的方式处理文件路径:使用 Path('目录') / '子目录' / '文件名' 这种方式使用 / 运算符拼接路径(比 os.path.join 更直观),并且可以调用 .resolve() 获取绝对路径、.exists() 检查是否存在。例如 p = Path('data') / 'logs' / 'app.log' 会生成一个跨平台的路径对象,支持后续的读写、迭代等操作,是现代 Python 处理路径的推荐方式。
python
from pathlib import Path
# 当前目录
current = Path.cwd()
print(current)
# 拼接路径
data_dir = Path("data") / "models" / "config.json"
print(data_dir) # data/models/config.json
# 用户主目录
home = Path.home()
print(home)
4.6.2 读写文件
在 Python 中,使用 pathlib 读写文件非常直观:对于文本文件,Path('文件路径').read_text(encoding='utf-8') 可一次性读取全部内容,而 Path('文件路径').write_text('内容', encoding='utf-8') 则可写入(覆盖)文本;对于二进制文件,则使用 .read_bytes() 和 .write_bytes()。此外,还可以通过 .open() 方法返回文件对象,配合 with 语句进行更精细的控制(如逐行读取)。这种方法避免了传统 open 函数需要手动关闭文件的繁琐。
python
from pathlib import Path
config = Path("config.json")
if config.exists():
content = config.read_text(encoding="utf-8")
print(content)
# 写入
output = Path("result.txt")
output.write_text("Hello, AI!", encoding="utf-8")
4.6.3 遍历目录
使用 pathlib 遍历目录时,最核心的方法是 .iterdir(),它返回当前目录下所有文件/子目录的 Path 对象生成器;若需按模式匹配(如所有 .txt 文件),可使用 .glob('*.txt');若要递归遍历所有子目录,则使用 .rglob('*.py')。例如 [p for p in Path('logs').iterdir() if p.is_file()] 可列出 logs 目录下的所有文件。这些方法返回的是生成器,内存友好,且支持链式调用与过滤。
python
from pathlib import Path
# 遍历当前目录下的所有 .py 文件
for py_file in Path(".").glob("*.py"):
print(py_file)
# 递归遍历(**/ 表示任意子目录)
for json_file in Path(".").glob("**/*.json"):
print(f"找到 JSON: {json_file}")
4.6.4 AI 场景:批量加载提示词文件
python
from pathlib import Path
prompts_dir = Path("./prompts")
# 创建提示词目录(如果不存在)
prompts_dir.mkdir(exist_ok=True)
# 写入几个示例提示词
(prompts_dir / "system_prompt.txt").write_text("你是一名专业的技术作家。", encoding="utf-8")
(prompts_dir / "user_prompt_1.txt").write_text("解释什么是注意力机制。", encoding="utf-8")
# 读取所有 .txt 文件
for prompt_file in prompts_dir.glob("*.txt"):
content = prompt_file.read_text(encoding="utf-8")
print(f"来自 {prompt_file.name}:{content}")
4.7 综合实战:AI 实验数据管理工具
结合文件、目录、JSON 等知识,创建一个简单的实验数据管理脚本。
python
import json
import os
from pathlib import Path
from datetime import datetime
class ExperimentTracker:
def __init__(self, base_dir="experiments"):
self.base_dir = Path(base_dir)
self.base_dir.mkdir(exist_ok=True)
def new_experiment(self, name, config):
"""创建一个新的实验文件夹,保存配置"""
exp_dir = self.base_dir / name
if exp_dir.exists():
print(f"实验 {name} 已存在,请换一个名字")
return False
exp_dir.mkdir()
# 保存配置
config_file = exp_dir / "config.json"
with open(config_file, "w", encoding="utf-8") as f:
json.dump(config, f, indent=2)
print(f"实验 {name} 创建成功,配置已保存")
return True
def save_result(self, exp_name, result_data):
"""保存实验结果到对应实验文件夹"""
exp_dir = self.base_dir / exp_name
if not exp_dir.exists():
print(f"实验 {exp_name} 不存在")
return
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
result_file = exp_dir / f"result_{timestamp}.json"
with open(result_file, "w", encoding="utf-8") as f:
json.dump(result_data, f, indent=2)
print(f"结果已保存到 {result_file}")
def list_experiments(self):
"""列出所有实验"""
experiments = [p.name for p in self.base_dir.iterdir() if p.is_dir()]
print("已有实验:", experiments)
return experiments
# 使用示例
tracker = ExperimentTracker()
# 创建一个新实验
config = {
"model": "gpt-4",
"temperature": 0.8,
"max_tokens": 500,
"dataset": "math_questions"
}
tracker.new_experiment("exp_001", config)
# 模拟实验结果
result = {
"accuracy": 0.85,
"total_tokens": 12500,
"cost_usd": 0.38,
"error_rate": 0.02
}
tracker.save_result("exp_001", result)
# 列出所有实验
tracker.list_experiments()
4.8 本章小结
| 操作类别 | 关键函数/模块 | AI 典型应用 |
|---|---|---|
| 路径操作 | os.path.join, Path |
拼接模型路径、数据路径 |
| 文本文件 | open(), read/write |
保存 API 日志、提示词 |
| JSON 文件 | json.dump, json.load |
保存配置、对话历史、评估结果 |
| CSV 文件 | csv.writer, csv.reader |
记录批量测试结果 |
| 目录管理 | os.mkdir, os.listdir, Path.glob |
按日期整理日志、批量加载配置文件 |
| 文件操作 | os.rename, shutil.move, Path.unlink |
重命名模型文件、移动旧数据 |
| 现代路径 | pathlib.Path |
所有路径操作推荐使用 |