【问题标题】:Getting glob to follow symlinks in Python让 glob 在 Python 中遵循符号链接
【发布时间】:2017-10-02 16:31:39
【问题描述】:

假设我有一个符号链接的子目录,如下所示:

subdir/
    folder/
        readme.txt
    symlink/ => ../hidden/
hidden/
    readme.txt

如果我运行以下代码:

>>> from pathlib import Path
>>> list(Path('./subdir/').glob('**/readme.txt'))

我希望结果是:

subdir/folder/readme.txt
subdir/symlink/readme.txt

但实际结果是:

subdir/folder/readme.txt

我发现这是因为(出于某种未记录的原因)** 运算符不遵循符号链接。

有没有办法切实改变这种配置?

【问题讨论】:

  • 这很奇怪,因为有一个 open issue 要求 glob 选择跟随符号链接。
  • @JeremyMcGibbon 你永远无法取悦所有人,嘿?
  • 此行为似乎是修复此问题的副作用:bugs.python.org/issue26012。 pathlib.py 的 _RecursiveWildcardSelector 类中的方法 _iterate_directories() 显式忽略符号链接。

标签: python python-3.x symlink


【解决方案1】:

pathlib.glob 也不适用于 ** 和符号链接。我发现了相关问题https://bugs.python.org/issue33428

作为 Python3 的替代方案,您可以将 glob.glob**recursive=True 选项一起使用(详见 https://docs.python.org/3/library/glob.html

In [67]: from glob import glob
In [71]: list(glob("./**/readme.txt", recursive=True))
Out[71]:
['./hidden/readme.txt',
 './subdir/folder/readme.txt',
 './subdir/symlink/readme.txt']

In [73]: list(glob("./**/readme.txt", recursive=False))
Out[73]: ['./hidden/readme.txt']

比较:

In [72]: list(Path('.').glob('**/readme.txt'))
Out[72]: [PosixPath('hidden/readme.txt'), PosixPath('subdir/folder/readme.txt')]

【讨论】:

    【解决方案2】:

    我以前从未使用过pathlib,因此您可以扩展此解决方案以利用它的一些功能,但我仅使用glob 来实现此功能。

    from glob import glob
    list(glob('./subdir/*/readme.txt'))
    

    输出:

    ['./subdir/folder/readme.txt', './subdir/symlink/readme.txt']
    

    如果您设置使用具有多个子目录深度的glob,则骇人听闻的解决方案是包含具有额外*/(例如./subdir/*/*/*/readme.txt)的变体,直到某个任意深度,并将结果连接起来每个变化。

    更合适的方法是编写一个具有您想要的行为的自定义函数(通过符号链接搜索任意深度),并以您想要的方式处理循环路径的情况。有关使用os.walk 执行此操作的提示,请参阅this question(请记住设置followlinks=True)。

    【讨论】:

    • Path.globglob 使用相同的功能 - 我发现的问题是 glob 在使用 ** 时不喜欢跟随符号链接。
    • 由于您的目录结构具有特定的深度,您是否有理由不能使用* 而不是**?有趣的是,glob in javascript** 具有相同的行为。
    • 我猜这种行为的原因是为了避免在创建目录循环的符号链接的情况下出现无限深度的问题。
    • 我正在尝试编写一个足够多的解决方案摘要,以便在一些案例场景中使用它。在某些情况下,readme.txt 文件可能被深埋
    • 更新了解决方案,以反映您对更深层次路径的需求。
    猜你喜欢
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    • 2012-09-19
    相关资源
    最近更新 更多