【问题标题】:Path manipulation in pythonpython中的路径操作
【发布时间】:2016-10-06 11:23:50
【问题描述】:

我到处查看 Stack Overflow,但找不到解决此问题的方法。

鉴于我有一个文件夹/文件作为字符串:"/path1/path2/path3/file" 我如何获取父文件夹及其父文件夹。换句话说,如果我想向上遍历一级"/path1/path2/path3" 或两级"/path1/path2" 如何从python 中的原始字符串路径中获取这些字符串值?

请注意,我不只是想要路径的片段(换句话说,不是['path1', 'path2', 'path3'] 的列表)而是"/path1/path2/path3"

【问题讨论】:

标签: python


【解决方案1】:

os.path.dirname() (doc) 是要走的路。它返回包含路径指向的对象的目录:

>>> import os.path
>>> os.path.dirname('/path1/path2/path3/file')
'/path1/path2/path3'

在这种情况下,您需要“祖父母”目录,因此只需使用该函数两次:

>>> parent = os.path.dirname('/path1/path2/path3/file')
>>> os.path.dirname(parent)
'/path1/path2'

如果您想执行任意次数,这里的函数可能会有所帮助:

def go_up(path, n):
    for i in range(n):
        path = os.path.dirname(path)

    return path

这里有一些例子:

>>> go_up('/path1/path2/path3/file', 1)
'/path1/path2/path3'
>>> go_up('/path1/path2/path3/file', 2)
'/path1/path2'
>>> go_up('/path1/path2/path3/file', 3)
'/path1'

【讨论】:

    【解决方案2】:

    您可以使用pathlib 模块:

    >>> path = pathlib.PurePath('/file1/file2/file3/file')
    >>> path.parts
    ('/', 'file1', 'file2', 'file3', 'file')
    >>> os.path.join(*path.parts[:-2])
    '/file1/file2'
    

    所以只需将path.parts[:-n] 放入n 级别即可。

    您也可以使用parents 属性:

    >>> path = pathlib.PurePath('/file1/file2/file3/file4/file5/file6')
    >>> path.parents[0]
    PurePosixPath('/file1/file2/file3/file4/file5')
    >>> path.parents[1]
    PurePosixPath('/file1/file2/file3/file4')
    >>> path.parents[4]
    PurePosixPath('/file1')
    

    所以要升级n 级别只需使用parents[n-1]

    要将*Path 对象转换为字符串,只需在其上调用str

    >>> str(path)
    '/file1/file2/file3/file4/file5/file6'
    

    【讨论】:

      【解决方案3】:

      除了所有其他答案之外,您还可以将os.path.join 函数与os.path.pardir 变量一起使用,该变量通常等于..

      >>> path = "some/random/path/to/process"
      >>> parent = os.path.pardir
      >>> grand_parent_path = os.path.join(path, parent, parent)
      >>> grand_parent_path
      'some/random/path/to/process\\..\\..'
      

      如果不想多次重复parent,可以使用多重列表:

      >>> os.path.join(path, *([parent] * 3))
      'some/random/path/to/process\\..\\..\\..'
      

      结果很丑,所以你可以使用os.path.normpath 函数让它更漂亮:

      >>> os.path.normpath(os.path.join(path, *([parent] * 3)))
      'some\\random'
      

      重要提示:这样做,您确定您的代码是可移植的

      【讨论】:

        【解决方案4】:

        os.path.split 会为你做这件事。里面还有很多其他有趣的功能。

        【讨论】:

        • 将路径名路径分成一对,(head, tail),其中 tail 是最后一个路径名组件,而 head 是导致该路径的所有内容。我怎样才能穿越两三层?
        • @RFVenter 在结果上多次调用函数?
        【解决方案5】:

        os.path.dirname 为您提供父目录。

        【讨论】:

        • 这不是我要求的。
        • 是的,这正是您所要求的。 >>> os.path.dirname("/path1/path2/path3/file") '/path1/path2/path3'
        • 引用问题:'或两个级别'
        • 2 级:os.path.dirname(os.path.dirname("/path1/path2/path3/file")) ...
        • 写一个函数,它接受一个路径和一个级别,并在路径上应用级别时间 os.path.dirname?
        【解决方案6】:
        '/'.join (originalPath.split ('/') [:-2])
        

        它会让你升 2 级。

        【讨论】:

        • 这可能会失败,例如,如果路径是使用 `` 作为分隔符的 Windows 路径。
        • 是的,但问题是关于 Linux 路径的。顺便说一句,作为一种习惯,我总是将路径转换为 ​​Linux 路径。但承认,os.path 是这项工作普遍接受的工具箱。我喜欢一个小工具箱,不过,有时我再也找不到锤子了……
        • 可以通过os.path.sep替换'/'来解决
        • @JacquesdeHooge 我同意,字符串是具体的,你的回答很好,很明显(duh)而且简洁。谢谢
        猜你喜欢
        • 2011-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-25
        • 1970-01-01
        • 2010-09-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多