Python函数:提取文件路径中的多个段

4
我想编写一个Python函数,能够接受文件路径,例如:
/abs/path/to/my/file/file.txt
并返回三个字符串变量:
- /abs - 根目录和路径中最上层的目录 - file - 路径中最下层的目录;file.txt的父级目录 - path/to/my - 路径中最上层和最下层目录之间的所有内容
伪代码如下:
def extract_path_segments(file):
    absPath = get_abs_path(file)
    top = substring(absPath, 0, str_post(absPath, "/", FIRST))
    bottom = substring(absPath, 0, str_post(absPath, "/", LAST))
    middle = str_diff(absPath, top, bottom)

    return (top, middle, bottom)

提前感谢您的任何帮助!

4个回答

5
你正在寻找与各种os.path模块函数一起使用的os.sep。只需按该字符拆分路径,然后重新组装您想要使用的部分即可。像这样:
import os

def extract_path_segments(path, sep=os.sep):
    path, filename = os.path.split(os.path.abspath(path))
    bottom, rest = path[1:].split(sep, 1)
    bottom = sep + bottom
    middle, top = os.path.split(rest)
    return (bottom, middle, top)

这个方法并不很好地处理Windows路径,因为\/都是合法的路径分隔符。在这种情况下,你还有一个驱动器号,所以你必须对其进行特殊处理。

>>> extract_path_segments('/abs/path/to/my/file/file.txt')
('/abs', 'path/to/my', 'file')

在Windows上不能使用"\""/"作为路径分隔符吗?我认为在这种情况下这不会起作用...(尽管我愿意不在Windows上工作;-) - mgilson
@mgilson:是的,Windows 两种格式都支持,但 os.sep 总是 \\。这很痛苦,所以我定义了一个关键字参数 sep,默认为 os.sep - Martijn Pieters
1
引用 the os.sep docs 的话:“请注意,仅知道这一点是不足以解析或连接路径名的 - 请使用 os.path.split() 和 os.path.join() - 但偶尔会有用处。 - Lauritz V. Thaulow
@lazyr:幸运的是,在Windows上,你还必须处理开头的驱动器号,而OP没有指定如何处理,所以我将忽略Windows情况。 :-) - Martijn Pieters
@lazyr,使用os.path.split()和os.path.join()甚至不会使代码变得更加复杂。 - John La Rooy
显示剩余2条评论

3

使用os.path.split

import os.path

def split_path(path):
    """
    Returns a 2-tuple of the form `root, list_of_path_parts`
    """
    head,tail = os.path.split(path)
    out = []
    while tail:
        out.append(tail)
        head,tail = os.path.split(head)
    return head,list(reversed(out))

def get_parts(path):
    root,path_parts = split_path(path)
    head = os.path.join(root,path_parts[0])
    path_to = os.path.join(*path_parts[1:-2])
    parentdir = path_parts[-2]
    return head,path_to,parentdir

head,path_to,parentdir = get_parts('/foo/path/to/bar/baz')
print (head)        #foo
print (path_to)     #path/to
print (parentdir)   #bar

符合文档建议?检查。跨平台?检查。这是正确的方法。需要注意的是,get_parts 需要绝对路径和标准化路径作为参数(例如 /abs/path/to/my/file/subdir/../file.txt 将失败),并且它不处理 Windows 网络挂载点 (\\server\share\abs\path\to\my\file\file.txt),但这些问题可以轻松解决 - Lauritz V. Thaulow

2

我们应该使用os.path.split()os.path.join()

>>> import os
>>> pth = "/abs/path/to/my/file/file.txt"
>>> parts = []
>>> while True:
...     pth, last = os.path.split(pth)
...     if not last:
...         break
...     parts.append(last)
...
>>> pth + parts[-1]
'/abs'
>>> parts[1]
'file'
>>> os.path.join(*parts[-2:1:-1])
'path/to/my'

作为一个函数
import os

def extract_path_segments(pth):
    parts = []
    while True:
        pth, last = os.path.split(pth)
        if not last:
            break
        parts.append(last)
    return pth + parts[-1], parts[1], os.path.join(*parts[-2:1:-1])

1
>>> p = '/abs/path/to/my/file/file.txt'
>>> r = p.split('/')
>>> r[1],'/'.join(r[2:-2]),r[-2]
('abs', 'path/to/my', 'file')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接