You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断pathlib.Path对象是否为另一个路径的子目录?

判断pathlib.Path是否为另一个路径的子目录

Python 3.9+ 推荐用法

pathlib.Path和PurePath从Python 3.9开始内置了**is_relative_to()**方法,能精准判断一个路径是否是另一个路径的子路径(或路径本身),完全规避字符串匹配的漏洞:

from pathlib import Path

root_dir = Path("/home/user/projects")
sub_dir = Path("/home/user/projects/utils")
unrelated_dir = Path("/home/user/downloads")

print(sub_dir.is_relative_to(root_dir))    # 输出 True
print(unrelated_dir.is_relative_to(root_dir))  # 输出 False

兼容Python 3.8及以下版本

如果你的环境是旧版Python,可以通过解析路径的父节点列表来判断:

from pathlib import Path

def is_subpath(child_path: Path, parent_path: Path) -> bool:
    # 先标准化路径,消除相对路径符号
    child = child_path.resolve()
    parent = parent_path.resolve()
    # 检查父路径是否在子路径的所有父节点中,或两者路径完全相同
    return parent in child.parents or child == parent

root_dir = Path("/home/user/projects")
sub_dir = Path("/home/user/projects/utils")
print(is_subpath(sub_dir, root_dir))  # 输出 True

修复你提供的压缩文件代码

你原来用字符串包含的判断逻辑存在误判风险(比如路径名称部分重叠时会出错),下面用is_relative_to()替换原有逻辑,优化后的代码如下:

import zipfile
import pathlib
import os
import logging

log = logging.getLogger(__name__)

with zipfile.ZipFile(fname, 'w') as zip:
    for f in files:
        myrelroot = relroot  # 当前压缩包的相对根路径
        try:
            f_path = pathlib.Path(f)
            relroot_path = pathlib.Path(relroot)
            # 判断当前文件是否在指定根路径范围内
            if not f_path.is_relative_to(relroot_path):
                myrelroot = None  # 不在范围内,避免生成../这类不安全路径
        except ValueError:
            # 路径格式不合法时也设为None
            myrelroot = None
        
        try:
            if myrelroot:
                arcname = os.path.relpath(f, myrelroot)
            else:
                # 不在范围内时,直接使用文件名作为归档名(可按需调整)
                arcname = pathlib.Path(f).name
            zip.write(f, arcname=arcname)
        except FileNotFoundError as e:
            log.warning(f"文件 '{f}' 未找到: {e}")
        else:
            log.info(f"正在将 {f} 添加到 {fname}")

字符串匹配的问题

假设你的根路径是/data/report,而某个文件路径是/data/report_card/file.csv,字符串匹配会错误地认为该文件在根路径范围内,但实际上两者毫无关系。is_relative_to()方法会基于路径的层级结构判断,不会出现这类误判。

内容的提问来源于stack exchange,提问作者MortenB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 08:35:35