开始前,会这些就够了
- 知道文件可以放在多层文件夹里
假设小林写了一段读学习笔记的程序,路径是 ./notes/todo.txt。在一个终端里能找到,换个目录再启动却说不存在。笔记没有搬家,变的可能是找路的起点:这串文字没写明完整地址,而是让程序从自己当前所在的位置出发。
下面用 Linux 常见的斜杠路径讲故事。我们只在纸面和字符串里走路,不打开实际文件,也不建立链接。学会之后,再看那些点号,就能先问清它们正在指哪个目录。
一个点是原地,两个点是上级
在这种路径中,单独一段 . 表示查找到这一步时的目录,.. 表示它的上级。比如从 /lesson 出发,notes/./todo.txt 是进入 notes、留在这里、再找 todo.txt;中间的点不是跳回 /lesson。它也不是 todo.txt 文件名里那个点,必须看整段名称;在根目录再遇到 ..,仍停留在根目录,不会出现一个更高的目录。
没有开头斜杠的是相对路径,通常相对于进程当前工作目录;也有接口让调用者明确指定另一个起点。以 / 开头的绝对路径则从进程看到的根目录开始。工作目录不自动等于脚本存放目录,所以换一种启动方式,原来的相对路径可能就找向别处。
整理地址文字,还没有上路
词法规范化听起来很抽象,其实就是只看写法,按规则整理多余片段。Python 的 posixpath.normpath 会做这样的计算;即使 missing 根本不存在,它也能给出一段整洁的结果。这里的函数没有询问电脑上到底有哪些目录。
下面明确选择 POSIX 风格,因此在 Windows 上也按同一套斜杠规则演示。PurePosixPath 也是不访问文件系统的路径工具,但它保留 ..;两个工具的职责不同,不能仅凭哪一个结果更短,就判断谁找到了正确文件。
import posixpath
from pathlib import PurePosixPath
samples = [
'notes/./todo.txt',
'notes/drafts/../todo.txt',
'missing/../todo.txt',
]
for raw in samples:
print('input:', raw)
print('norm: ', posixpath.normpath(raw))
print('pure: ', PurePosixPath(raw))怎样运行:保存为 path_words.py,用 Python 3.10 或更新版本运行:python path_words.py。只使用标准库处理字符串,不访问示例目录。
运行后对照结果
input: notes/./todo.txt
norm: notes/todo.txt
pure: notes/todo.txt
input: notes/drafts/../todo.txt
norm: notes/todo.txt
pure: notes/drafts/../todo.txt
input: missing/../todo.txt
norm: todo.txt
pure: missing/../todo.txt符号链接像一张转交地址的纸条
符号链接可以先想成一张写着另一个路径的纸条。假设 /lesson/shortcut 指向 /archive/week1,相关目录都存在且可访问。按 Linux 通常跟随中间符号链接的方式查找 /lesson/shortcut/../cover.txt 时,先跟纸条到 week1,再看 ..,就会去 /archive 下找 cover.txt。
若只在文字上把 shortcut/.. 划掉,结果却是 /lesson/cover.txt,已经是另一个位置。PurePosixPath 保留 ..,正是因为仅看字面无法知道前一段会不会把人带往别处。这个故事展示一次中途转向,不是一个完整的文件系统模拟。
真正找文件,还要经过每一站
实际查找还要面对文字整理没有回答的问题:中间目录存在吗,能进入吗,某一段是普通文件还是链接?例如把 missing/../todo.txt 直接交给 Linux 查找,若第一段不存在,就可能在那里失败,并不会因为纸面上能消去它而自动跳过检查。
排查“文件明明在却找不到”时,先记下程序的工作目录和收到的原始路径,再看真实查找报告的错误。需要解析实际链接时,应使用会访问文件系统的工具,并理解它遇到缺失目录时的行为;得到一串绝对路径文字,也还不能单凭外观证明目标存在。
记住这三点
- . 与 .. 表示查找过程中当前目录和上级目录;相对路径还需要明确起点。
- 词法整理只改路径写法,既不证明文件存在,也不解析真实符号链接。
- 中间的链接可能改变后续 .. 的位置,不能一律把前一段与 .. 直接划掉。
别把例子用过头
- 本文以 Linux / POSIX 风格说明,Windows 盘符、网络共享路径及某些工具的处理规则不能直接套用。
- 示例没有创建目录或链接;链接故事是基于明确假设的纸面推演,不是本机查找结果。
- 中间链接与最后一段链接的处理不一定相同,是否跟随最终链接取决于调用的接口。
自己试一小步
同一份找路说明换了起点,或者中间多了一张转向纸条,会去哪里?
- 在纸上画两个起点,每个都有不同的 notes 子目录,给它们同一段相对路径。
- 只改其中一条路线的某个目录为指向另一个目录的链接,逐段标出经过的位置。
- 把代码里的一个输入换成自己的路径文字,分别记录纯文字输出与纸面查找过程。
做到这些,就算完成
- 是否明确每次从哪里开始,而不是默认从脚本所在目录开始?
- 是否在遇见 .. 之前先处理前面的目录或链接?
- 是否把文字计算、假设下推演和真实文件存在性分开记录?
查原始资料
想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。
- Linux man-pages:path_resolution(7) (新标签页)↗
路径查找的起点、逐段查找、中间符号链接、. 和 .. 的含义,以及目录缺失或无权进入的错误。
- Python 3.14:os.path 与 normpath (新标签页)↗
显式使用 posixpath 的跨平台规则选择、normpath 的纯文字整理,以及含链接时可能改变原路径含义。
- Python 3.14:pathlib 的 Pure paths (新标签页)↗
Pure 路径不访问文件系统、单点会折叠而双点被保留,以及符号链接使直接消去前一段不可靠。
找一份资料继续练
先选一项,按下面的范围继续学;不必从头读完整门课程。
沿路径找文件:符号链接把下一步带到哪里? (新标签页)↗
按手册三个步骤画出符号链接之后的查找路径,明确目录存在、权限允许、跟随链接等前提。
查看学习准备与访问说明 →