为什么pathlib.Path.glob(**) 和rglob(**)一样支持递归?

我的理解:pathlib.Path.glob 不支持递归,

P = pathlib.Path('D:/id')
P.glob(**)   ##期待效果:只列出一级子目录  -- 不一致,实际列出所有子目录
P.glob(*/**)  ##期待效果,只列出二级子目录。-- 不一致,实际二级及以下所有子目录
P.rglob(**)  ## 期待效果:列出所有子目录  -- 一致

P.glob(*)   ## 期待效果: 只列出一级子目录和文件 --一致
P.rglob(*)  ## 期待效果: 列出一级子目录和所有文件 -- 一致。 

疑问:为什么 glob在两个*时不按预期工作?是本来设定还是bug?
如果是本来设定,和rglob完全重复,没有必要呀。

Jason990420
最佳答案

Path.glob(pattern)

解析相对于此路径的通配符 pattern,产生所有匹配的文件:

>>>
>>> sorted(Path('.').glob('*.py'))
[PosixPath('pathlib.py'), PosixPath('setup.py'), PosixPath('test_pathlib.py')]
>>> sorted(Path('.').glob('*/*.py'))
[PosixPath('docs/conf.py')]

"**" 模式表示 “此目录以及所有子目录,递归”。换句话说,它启用递归通配:

>>>
>>> sorted(Path('.').glob('**/*.py'))
[PosixPath('build/lib/pathlib.py'),
 PosixPath('docs/conf.py'),
 PosixPath('pathlib.py'),
 PosixPath('setup.py'),
 PosixPath('test_pathlib.py')]


Path.rglob(pattern)

这就像调用 Path.glob 时在给定的相对 pattern 前面添加了"**/"

>>>
>>> sorted(Path().rglob("*.py"))
[PosixPath('build/lib/pathlib.py'),
 PosixPath('docs/conf.py'),
 PosixPath('pathlib.py'),
 PosixPath('setup.py'),
 PosixPath('test_pathlib.py')]
3周前 评论
讨论数量: 4
Jason990420

问题内容有误, 而且显示的格式错误, 请更正 …

  • libpath -> pathlib
  • 使用某些特殊字符, 如 _, #, *, 前面加反斜杠号避免被转义
3周前 评论
Jason990420

Path.glob(pattern)

解析相对于此路径的通配符 pattern,产生所有匹配的文件:

>>>
>>> sorted(Path('.').glob('*.py'))
[PosixPath('pathlib.py'), PosixPath('setup.py'), PosixPath('test_pathlib.py')]
>>> sorted(Path('.').glob('*/*.py'))
[PosixPath('docs/conf.py')]

"**" 模式表示 “此目录以及所有子目录,递归”。换句话说,它启用递归通配:

>>>
>>> sorted(Path('.').glob('**/*.py'))
[PosixPath('build/lib/pathlib.py'),
 PosixPath('docs/conf.py'),
 PosixPath('pathlib.py'),
 PosixPath('setup.py'),
 PosixPath('test_pathlib.py')]


Path.rglob(pattern)

这就像调用 Path.glob 时在给定的相对 pattern 前面添加了"**/"

>>>
>>> sorted(Path().rglob("*.py"))
[PosixPath('build/lib/pathlib.py'),
 PosixPath('docs/conf.py'),
 PosixPath('pathlib.py'),
 PosixPath('setup.py'),
 PosixPath('test_pathlib.py')]
3周前 评论

如果是需要指定深度的子目录, 好像没有特别好的办法? 原本以为 pathlib.Path.glob(/*/) 可以控制最多查找2级目录,现在除了自己做判断忽略3级之后的,还有一步到位的过滤方法没有?

3周前 评论
Jason990420
>>> from pathlib import Path
>>> path = Path('C:/Windows/Boot')
>>> list(path.glob("*"))        # find all files and subdirectories just under it
[WindowsPath('C:/Windows/Boot/BootDebuggerFiles.ini'), WindowsPath('C:/Windows/Boot/DVD'), WindowsPath('C:/Windows/Boot/EFI'), WindowsPath('C:/Windows/Boot/Fonts'), WindowsPath('C:/Windows/Boot/Misc'), WindowsPath('C:/Windows/Boot/PCAT'), WindowsPath('C:/Windows/Boot/Resources')]
>>> list(path.glob("*.*"))      # find all files just under it
[WindowsPath('C:/Windows/Boot/BootDebuggerFiles.ini')]
>>> [file for file in path.glob("*") if file.is_dir()]      # get all subdirectories just under it
[WindowsPath('C:/Windows/Boot/DVD'), WindowsPath('C:/Windows/Boot/EFI'), WindowsPath('C:/Windows/Boot/Fonts'), WindowsPath('C:/Windows/Boot/Misc'), WindowsPath('C:/Windows/Boot/PCAT'), WindowsPath('C:/Windows/Boot/Resources')]
3周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!