第 2-2 课:文件与目录操作
一、本课目标
完成本课后,你将能够:
- 解释文件、目录和路径分别是什么;
- 使用
Path表示和组合路径; - 创建练习目录;
- 安全地写入、追加和读取文本文件;
- 检查路径是否存在,以及它是不是文件;
- 遍历目录中的文件;
- 说明文件操作可能带来的副作用。
二、前置知识
学习本课前,需要掌握:
- 字符串、变量和布尔值;
- 条件判断与循环;
- 函数、参数和返回值;
- 模块、导入和程序入口判断。
上一课学习了模块。本课将从 Python 标准库中导入 pathlib 模块提供的 Path。
三、文件、目录和路径是什么
文件(File)是保存在计算机中的一份数据,例如:
- Python 程序
practice.py; - 文本文件
learning_notes.txt; - 图片文件
photo.png。
目录(Directory)也常被称为文件夹,用于组织文件和其他目录。
路径(Path)用于描述文件或目录在计算机中的位置。例如:
02_python进阶/2_2_文件与目录操作/runtime_data/learning_notes.txt
可以把路径理解为从一个位置找到目标文件所经过的路线。
四、为什么使用 Path
不同操作系统表示路径的方式可能不同。Windows 常见反斜杠 \,其他系统常见正斜杠 /。手工拼接路径容易写错。
pathlib 是 Python 标准库中的路径处理模块。Path 是它提供的路径对象:
from pathlib import Path
lesson_dir = Path(__file__).parent
data_dir = lesson_dir / "runtime_data"
对象(Object)可以暂时理解为“同时保存数据和操作能力的值”。面向对象课程会详细讲解。
这里:
__file__是 Python 自动提供的特殊变量,表示当前文件的位置;Path(__file__)把位置转换成路径对象;.parent得到当前文件所在的目录;/ "runtime_data"在原路径后面组合新的目录名。
这里的 / 不是数学除法。Path 对象把它设计成了清晰的路径组合写法。
五、相对路径与绝对路径
相对路径(Relative Path)表示相对于当前工作位置的路线:
runtime_data/learning_notes.txt
绝对路径(Absolute Path)从磁盘或系统根位置开始,完整描述目标位置。在 Windows 中可能类似:
F:\PyCharm\PythonLearn\02_python进阶\2_2_文件与目录操作
本课通过 Path(__file__).parent 取得课程目录。这样无论从项目根目录还是课程目录启动示例,数据都会写入本课自己的 runtime_data。
六、创建目录
data_dir.mkdir(parents=True, exist_ok=True)
mkdir() 表示创建目录:
parents=True:需要时一并创建缺少的上级目录;exist_ok=True:目录已经存在时不报错。
如果没有 exist_ok=True,第二次运行程序时可能出现:
FileExistsError
中文解释:程序想创建的文件或目录已经存在。
七、写入文本文件
notes_file.write_text(
"第一条:学习使用 Path 表示路径。\n",
encoding="utf-8",
)
write_text() 会创建文件并写入文本。如果文件已经存在,它会覆盖原有内容。
覆盖意味着旧内容会被替换,可能难以恢复。因此:
- 练习时只操作专用数据目录;
- 写入前确认路径是否正确;
- 不要把重要文件路径交给练习程序;
- 中文文本明确使用
encoding="utf-8"。
编码(Encoding)是文字与计算机数据之间的转换规则。UTF-8 是常用的文字编码,可以保存中文和多种语言。
字符串中的 \n 表示换行。
八、追加文本文件
覆盖写入会清空旧内容。希望在文件末尾增加内容时,可以使用追加模式:
with notes_file.open("a", encoding="utf-8") as file:
file.write("第二条:学习读取和追加文件。\n")
打开模式(File Mode)"a" 中的字母来自 append,表示追加。
with 语句会在代码块结束后帮助关闭文件。即使以后文件操作发生错误,也更容易正确释放文件资源。
本课先记住固定结构:
with path.open("a", encoding="utf-8") as file:
file.write("需要追加的内容")
九、读取文本文件
content = notes_file.read_text(encoding="utf-8")
print(content)
read_text() 会读取整个文本文件,并返回一个字符串。
如果文件不存在,可能出现:
FileNotFoundError
中文解释:Python 在指定路径没有找到需要读取的文件。
可以先检查文件是否存在:
if notes_file.exists():
content = notes_file.read_text(encoding="utf-8")
十、检查路径
常用检查方法:
path.exists()
path.is_file()
path.is_dir()
exists():路径是否存在;is_file():路径是否存在并且是文件;is_dir():路径是否存在并且是目录。
这些方法返回布尔值 True 或 False,可以与条件判断配合使用。
十一、遍历目录
for path in data_dir.iterdir():
if path.is_file():
print(path.name)
iterdir() 会提供目录中的每一项。每一项仍然是 Path 对象:
path.name表示文件或目录的名称;path.is_file()判断它是否是文件。
本课只遍历当前目录,不递归进入更深层目录。递归表示一个操作继续处理内部的子目录,属于后续扩展内容。
十二、示例文件与数据影响
本课文件结构:
02_python进阶/2_2_文件与目录操作/
├── .gitignore
├── README.md
├── file_directory_example.py
└── practice.py
运行示例后会产生:
runtime_data/
└── learning_notes.txt
运行练习后应产生:
practice_data/
└── diary.txt
这两个数据目录都被本课 .gitignore 忽略,不会加入 Git。程序不会操作课程目录之外的文件。
每次运行完整示例时,learning_notes.txt 会先被写入初始内容,再追加第二条记录,因此结果不会无限重复增加。
十三、运行方法
在 PowerShell 中进入项目根目录:
cd F:\PyCharm\PythonLearn
运行完整示例:
python .\02_python进阶\2_2_文件与目录操作\file_directory_example.py
完成练习后运行:
python .\02_python进阶\2_2_文件与目录操作\practice.py
十四、运行结果
完整示例的预期结果类似:
数据目录已准备:runtime_data
初始内容已写入:learning_notes.txt
新的学习记录已追加。
学习记录内容:
第一条:学习使用 Path 表示路径。
第二条:学习读取和追加文件。
数据目录中的文件:
- learning_notes.txt
然后可以打开 runtime_data/learning_notes.txt,确认文件内容与终端输出一致。
十五、关键代码执行顺序
运行 file_directory_example.py 时:
- 导入
Path; - 根据当前文件位置准备课程目录、数据目录和文件路径;
- 定义文件操作函数;
- 入口判断成立,调用
main(); - 创建
runtime_data; - 覆盖写入初始记录;
- 在文件末尾追加一条记录;
- 读取并输出完整内容;
- 遍历数据目录并输出文件名。
先创建目录再写文件非常重要。目录不存在时,直接写入内部文件会失败。
十六、常见错误
16.1 手工拼接路径
不推荐:
file_path = lesson_dir + "/runtime_data/notes.txt"
lesson_dir 是 Path 对象,不能直接与普通字符串这样相加。使用:
file_path = lesson_dir / "runtime_data" / "notes.txt"
16.2 忘记创建目录
在 runtime_data 不存在时直接写入内部文件,会出现 FileNotFoundError。应先调用 mkdir()。
16.3 忘记指定中文编码
读取或写入中文时未指定 UTF-8,可能出现乱码或编码错误。请在读写两端都使用 encoding="utf-8"。
16.4 混淆覆盖和追加
write_text()会覆盖原内容;open("a")会在末尾追加内容。
操作重要文件前必须确认自己需要哪一种行为。
16.5 忘记关闭文件
手动调用 open() 后如果忘记关闭文件,可能造成资源占用。本课使用 with 自动管理文件。
16.6 路径指向项目外部
练习时不要使用系统目录、桌面文件或其他项目文件。把所有练习数据限制在本课的 practice_data 中。
十七、课堂练习
打开 practice.py,依次完成:
- 准备练习目录和日记文件路径;
- 创建
practice_data; - 写入第一条日记;
- 追加第二条日记;
- 读取并输出完整内容;
- 检查文件是否存在并遍历目录。
每完成一部分就运行一次。不要直接复制参考答案。
十八、参考答案
请先独立完成练习,再展开查看。
查看参考答案
from pathlib import Path
lesson_dir = Path(__file__).parent
practice_dir = lesson_dir / "practice_data"
diary_file = practice_dir / "diary.txt"
practice_dir.mkdir(parents=True, exist_ok=True)
print("练习目录已准备。")
first_entry = "今天学习了文件与目录。\n"
diary_file.write_text(first_entry, encoding="utf-8")
print("日记已写入。")
with diary_file.open("a", encoding="utf-8") as file:
file.write("我会使用 Path 处理路径。\n")
print("日记已追加。")
content = diary_file.read_text(encoding="utf-8")
print("日记内容:")
print(content, end="")
if diary_file.exists():
print("日记文件存在。")
print("练习目录中的文件:")
for path in practice_dir.iterdir():
if path.is_file():
print(path.name)
十九、本课小结
- 文件保存数据,目录用于组织文件,路径描述它们的位置;
Path可以清晰地表示和组合路径;mkdir()可以创建目录;write_text()可以写入文本,但会覆盖原内容;open("a")可以追加内容;read_text()可以读取整个文本文件;with可以帮助正确关闭文件;exists()、is_file()和is_dir()可以检查路径;iterdir()可以遍历目录;- 文件操作存在副作用,必须限制操作范围并确认目标路径。
二十、验收标准
完成本课时,应满足:
- 可以解释文件、目录、相对路径和绝对路径;
- 可以使用
Path(__file__).parent定位当前课程目录; - 可以使用
/组合Path路径; - 可以创建已经存在也不会报错的目录;
- 可以正确写入、追加和读取中文文本;
- 可以解释覆盖写入与追加写入的区别;
- 可以使用
with打开文件; - 可以检查路径并遍历目录中的文件;
- 练习数据只出现在
practice_data中; - 运行两次练习,程序都不会崩溃;
- 最终日记内容不会因为重复运行而无限增加。