10

如果给我一个字符串形式的路径,例如“~/pythoncode/*.py”,那么将它全局化的最佳方法是什么pathlib

使用 pathlib,有一种使用 glob 附加到路径的方法:

p = pathlib.Path('~/pythoncode/').expanduser().glob('*.py')

但是,例如,这不起作用,因为用户没有展开:

p = pathlib.Path().glob('~/pythoncode/*.py')

这会产生一个异常,因为我没有提供任何参数glob()

p = pathlib.Path('~/pythoncode/*.py').expanduser().glob()

有没有办法做到这一点pathlib,或者我必须先解析字符串?

4

3 回答 3

11

如果您从字符串开始"~/pythoncode/*.py"并且想要扩展和全局,则需要先拆分路径。幸运的是 pathlib 提供.name.parent帮助

def expandpath(path_pattern) -> Iterable[Path]:
    p = Path(path_pattern)
    return Path(p.parent).expanduser().glob(p.name)

expandpath("~/pythonpath/*.py")

请注意,这个简单的解决方案仅在仅name包含 glob 时才有效,它不适用于路径其他部分中的 glob,例如:~/python*/*.py. 一个更复杂的更通用的解决方案:

def expandpath(path_pattern) -> Iterable[Path]:
    p = Path(path_pattern).expanduser()
    parts = p.parts[p.is_absolute():]
    return Path(p.root).glob(str(Path(*parts)))

expandpath("~/python*/*.py")

注2:上述函数失败IndexError: tuple index out of range)与这些退化的路径:'',,,'.''/'

于 2018-06-29T19:38:29.057 回答
6

pathlib.Path.glob不支持绝对(非相对)路径模式,但支持glob.glob

from glob import glob
from pathlib import Path

paths = [Path(p) for p in glob('/foo/*/bar')]

或与Path.expanduser

paths = [Path(p) for p in glob(str(Path('~/.bash*').expanduser()))]
于 2019-05-30T10:36:13.837 回答
0

我发现我真的想要内联扩展。这并不像我想象的那么容易。

无论如何,这就是我所拥有的。只进行了简单的测试,但让我知道它适合你的地方,我会编辑它。

def expand_pathglobs(pathparts, basepaths=None):
    # Logic:
    # 0. Argue with a Path(str).parts and optional ['/start','/dirs'].
    # 1. for each basepath, expand out pathparts[0] into "expandedpaths"
    # 2. If there are no more pathparts, expandedpaths is the result.
    # 3. Otherwise, recurse with expandedpaths and the remaining pathparts.
    # eg: expand_pathglobs('/tmp/a*/b*')
    #   --> /tmp/a1/b1
    #   --> /tmp/a2/b2

    if isinstance(pathparts, str) or isinstance(pathparts, Path):
        pathparts = Path(pathparts).parts

    if basepaths == None:
        return expand_pathglobs(pathparts[1:], [Path(pathparts[0])])
    else:
        assert pathparts[0] != '/'

    expandedpaths = []
    for p in basepaths:
        assert isinstance(p, Path)
        globs = p.glob(pathparts[0])
        for g in globs:
            expandedpaths.append(g)

    if len(pathparts) > 1:
        return expand_pathglobs(pathparts[1:], expandedpaths)

    return expandedpaths
于 2019-03-01T00:07:45.797 回答