如何确定路径是否是另一个路径的子目录?

时间:2012-01-13 17:08:29

标签: python file

我获得了检查文件所需的路径列表。当然,如果给我一个root和一个子目录,则不需要处理子目录。例如

c:\test  // process this
c:\test\pics // do not process this
c:\test2 // process this

如何判断(跨平台)路径不是另一个路径的子目录。最好是我希望这是跨平台的,并且我不担心符号链接,只要它们不是循环的(更糟糕的是我最终处理数据两次)。

更新:这是我最终使用的代码,感谢@ F.J

   def unique_path_roots(paths):
    visited = set()
    paths = list(set(paths))

    for path in sorted(paths,key=cmp_to_key(locale.strcoll)):
        path = normcase(normpath(realpath(path)))

        head, tail = os.path.split(path)
        while head and tail:
            if head in visited:
                break
            head, tail = os.path.split(head)
        else:
            yield path
            visited.add(path)

5 个答案:

答案 0 :(得分:8)

def is_subdir(path, directory):
    path = os.path.realpath(path)
    directory = os.path.realpath(directory)

    relative = os.path.relpath(path, directory)

    if relative.startswith(os.pardir):
        return False
    else:
        return True

答案 1 :(得分:6)

我会维护一组你已经处理过的目录,然后对每个新路径进行检查,看看在处理之前它的任何父目录是否已存在于该集合中:

import os.path

visited = set()
for path in path_list:
    head, tail = os.path.split(path)
    while head and tail:
        if head in visited:
            break
        head, tail = os.path.split(head)
    else:
        process(path)
        visited.add(path)

请注意,应对path_list进行排序,以便子目录始终位于其父目录之后(如果存在)。

答案 2 :(得分:2)

跟踪您已经处理过的目录(以规范化形式),如果您已经看过它们,请不要再次处理它们。这样的事情应该有效:

from os.path import realpath, normcase, sep

dirs = [r"C:\test", r"C:\test\pics", r"C:\test2"]

processed = []

for dir in dirs:
    dir = normcase(realpath(dir)) + sep
    if not any(dir.startswith(p) for p in processed):
        processed.append(dir)
        process(dir)            # your code here

答案 3 :(得分:0)

修正和简化的jgoeders版本:

def is_subdir(suspect_child, suspect_parent):
    suspect_child = os.path.realpath(suspect_child)
    suspect_parent = os.path.realpath(suspect_parent)

    relative = os.path.relpath(suspect_child, start=suspect_parent)

    return not relative.startswith(os.pardir)

答案 4 :(得分:0)

这是我提出的is_subdir效用函数。

  • Python3.x兼容(适用于bytesstr,匹配os.path,同时支持两者。)
  • 规范化路径以进行比较。
    (父级层次结构和案例在ms-windows上工作)。
  • 避免使用os.path.relpath,如果路径位于不同的驱动器上,则会在ms-windows上引发异常。 (C:\foo - > D:\bar

代码:

def is_subdir(path, directory):
    """
    Returns true if *path* in a subdirectory of *directory*.
    """
    import os
    from os.path import normpath, normcase, sep
    path = normpath(normcase(path))
    directory = normpath(normcase(directory))
    if len(path) > len(directory):
        sep = sep.encode('ascii') if isinstance(directory, bytes) else sep
        if path.startswith(directory.rstrip(sep) + sep):
            return True
    return False