如何使用通配符获取路径名字符串并使用 pathlib 解析 glob?
How to take a pathname string with wildcards and resolve the glob with pathlib?
如果给我一个字符串形式的路径,例如“~/pythoncode/*.py”,那么在 pathlib
中将其 glob 化的最佳方式是什么?
使用 pathlib,有一种使用 glob 附加到路径的方法:
p = pathlib.Path('~/pythoncode/').expanduser().glob('*.py')
但是,例如,这不起作用,因为用户未展开:
p = pathlib.Path().glob('~/pythoncode/*.py')
这会生成一个异常,因为我没有向 glob()
:
提供任何参数
p = pathlib.Path('~/pythoncode/*.py').expanduser().glob()
在 pathlib
中有没有办法做到这一点,还是我必须先解析字符串?
如果您从字符串 "~/pythoncode/*.py"
开始,并且想要扩展和 glob,则需要先拆分路径。幸运的是 pathlib 提供了 .name
和 .parent
来帮助 you out:
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
) 具有这些退化路径:''
、'.'
、'/'
我发现我真的想要内联扩展。这并不像我想象的那么容易。
无论如何,这就是我所拥有的。仅进行了简单的测试,但请告诉我它适合您的地方,我会对其进行编辑。
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
pathlib.Path.glob
does not support absolute (non-relative) path patterns, but 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()))]
如果给我一个字符串形式的路径,例如“~/pythoncode/*.py”,那么在 pathlib
中将其 glob 化的最佳方式是什么?
使用 pathlib,有一种使用 glob 附加到路径的方法:
p = pathlib.Path('~/pythoncode/').expanduser().glob('*.py')
但是,例如,这不起作用,因为用户未展开:
p = pathlib.Path().glob('~/pythoncode/*.py')
这会生成一个异常,因为我没有向 glob()
:
p = pathlib.Path('~/pythoncode/*.py').expanduser().glob()
在 pathlib
中有没有办法做到这一点,还是我必须先解析字符串?
如果您从字符串 "~/pythoncode/*.py"
开始,并且想要扩展和 glob,则需要先拆分路径。幸运的是 pathlib 提供了 .name
和 .parent
来帮助 you out:
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
) 具有这些退化路径:''
、'.'
、'/'
我发现我真的想要内联扩展。这并不像我想象的那么容易。
无论如何,这就是我所拥有的。仅进行了简单的测试,但请告诉我它适合您的地方,我会对其进行编辑。
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
pathlib.Path.glob
does not support absolute (non-relative) path patterns, but 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()))]