Python:判断路径是不是在某个目录下面,`Path.is_relative_to()` 挺顺手

64 次浏览7 条回复

有时就是想确认一个路径是不是落在某个目录里,不想自己拆字符串。

环境:Python 3.9+,只用标准库。

from pathlib import Path

base = Path('/tmp/work')
paths = [
    Path('/tmp/work/a.txt'),
    Path('/tmp/work/sub/b.txt'),
    Path('/tmp/other.txt'),
]

for p in paths:
    print(p, p.is_relative_to(base))

这个比手写前缀判断稳一点,尤其是路径层级多的时候。

补一句:这个更像是在看路径对象的层级关系,不是拿来当真正的安全边界校验用的。要是中间可能有 symlink,还是得再小心一点。平时做参数检查挺顺手。

过Lv1#1

补一句:这个更像是在看路径对象的层级关系,不是拿来当真正的安全边界校验用的。要是中间可能有 symlink,还是得再小心一点。平时做参数检查挺顺手。

顺手补个小坑:如果路径里可能有 ..,或者会碰到符号链接,is_relative_to() 更适合做层级判断,不太适合单独当边界校验。真要严一点,我一般会先把路径规整一下再看。

别熬夜啦Lv1#2

顺手补个小坑:如果路径里可能有 ..,或者会碰到符号链接,is_relative_to() 更适合做层级判断,不太适合单独当边界校验。真要严一点,我一般会先把路径规整一下再看。

对,is_relative_to() 更像层级判断。我一般会先 resolve(strict=False) 再比一下,至少把 .. 规整掉;但碰到不存在的路径、符号链接这些,还是别把它当最终安全判断。

问问Lv1#3

对,is_relative_to() 更像层级判断。我一般会先 resolve(strict=False) 再比一下,至少把 .. 规整掉;但碰到不存在的路径、符号链接这些,还是别把它当最终安全判断。

还有个小坑:is_relative_to() 是按路径对象本身来比,最好先把输入规整一下,不然带 .. 的时候看起来会有点绕。做参数检查我会把它当‘先筛一层’,不是最终边界校验。

过Lv1#4

还有个小坑:is_relative_to() 是按路径对象本身来比,最好先把输入规整一下,不然带 .. 的时候看起来会有点绕。做参数检查我会把它当‘先筛一层’,不是最终边界校验。

再补一点:如果 base 本身是相对路径,最好先统一成绝对路径再比。否则工作目录一变,结果就容易看着怪怪的。这个小东西我一般只拿来做前置判断,不拿它当最终兜底。

隔壁空白Lv1#5

再补一点:如果 base 本身是相对路径,最好先统一成绝对路径再比。否则工作目录一变,结果就容易看着怪怪的。这个小东西我一般只拿来做前置判断,不拿它当最终兜底。

顺手补个 Windows 小坑:同一套逻辑放到不同盘符时,is_relative_to() 会直接判不在下面。平时拼临时目录还好,真要跨盘就得先想清楚基准路径是不是一致。

补个兼容写法:老版本没有 is_relative_to() 的话,可以用 p.relative_to(base) 试一下,能成功就说明在下面,抛 ValueError 就不是。手感差不多,就是多一层异常。