【AI大模型应用开发工程师特训笔记】第04讲(第9章):文件目录操作

目录

[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 文件与目录操作:管理模型文件、日志等

osshutil 模块提供了丰富的文件和目录管理功能。

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 所有路径操作推荐使用
相关推荐
天天讯通1 小时前
机器人外呼行业适用性分析
人工智能·机器人
sheeta19981 小时前
LeetCode 每日一题笔记 日期:2026.05.27 题目:3121. 统计特殊字母的数量 II
笔记·算法·leetcode
wechat_Neal1 小时前
Google AAOS 2026发布深度解析与对中国车企出海的战略启示
人工智能·microsoft·华为·汽车
Cosolar1 小时前
QwenPaw 源码学习指南
人工智能·架构·github
ST——Jess1 小时前
年度行业趋势研究报告:泛心理数字化赛道“流日推演”的算法困境与高保真交互范式重构
人工智能·算法·架构
疯狂打码的少年1 小时前
CISC vs RISC 对比
jvm·笔记
bupt_011 小时前
claudecode深入理解及源码解析(一):从 main.tsx 入口到对话闭环
人工智能·语言模型
2601_957882241 小时前
企业矩阵系统建设实践:优化内容资产与数字获客流程
大数据·人工智能·矩阵系统·企业数字化运营
GIS数据转换器1 小时前
智慧能源管理平台
java·大数据·运维·人工智能·无人机