os.walk()是否漏掉了指向目录的符号链接?

3 投票
2 回答
4250 浏览
提问于 2025-04-17 13:25

我有一个文件夹,里面有一些文件、一些子文件夹,还有一些指向文件的符号链接和指向文件夹的符号链接。

当我在这个文件夹里用os.walk(),并把followlinks设置为false时,我能在文件名列表中看到文件和指向文件的符号链接,而在目录名列表中看到文件夹。但是,指向文件夹的符号链接却没有出现在任何地方。这是Python的一个bug,还是一个特性,或者是我做错了什么?

我原本期待指向文件夹的符号链接能出现在文件名列表中,因为它们不是文件夹,而是符号链接,而其他指向文件的符号链接却能出现在文件名列表里。

举个例子:文件夹foo里包含以下内容:

-rw-rw-r-- 4 rikno staff 136 Jan 14 11:10 firefox
lrwxr-xr-x 1 rikno staff   5 Jan 23 13:29 latex -> tetex
lrwxr-xr-x 2 rikno staff  68 Jan 14 11:10 mozilla -> firefox
drwxrwxr-x 3 rikno staff 102 Jan 23 13:29 tetex

我期待在第一次调用os.walk('foo')时返回

('foo', ['tetex'], ['firefox', 'latex', 'mozilla'])

或者至少返回

('foo', ['latex', 'tetex'], ['firefox', 'mozilla'])

但我得到的却是

('foo', ['tetex'], ['firefox', 'mozilla'])

而且我从来没有看到关于符号链接latex的信息(它指向文件夹tetex)

解决方案:

好的,结果是

('foo', ['latex', 'tetex'], ['firefox', 'mozilla'])

所以指向文件夹的符号链接出现在目录名列表中。

我最开始以为指向文件夹的符号链接会在文件名列表中,所以从来没有查看目录名列表。当我在代码和文件系统中实验,试图找出链接在哪里或者为什么链接“缺失”时,我不小心搞混了我的结果。

抱歉问这个问题。

2 个回答

3

你提到你在调用 os.walk() 时把 followlinks 设置为 False。那么,这就是 正常的表现

默认情况下,walk() 不会进入指向目录的符号链接。如果你想访问这些符号链接指向的目录,可以把 followlinks 设置为 True,前提是你的系统支持这种功能。

2

在我的电脑上,os.walk() 确实能显示所有的符号链接(sym links):

>>> os.walk("foo").next()
('foo', ['tetex', 'latex'], ['mozilla', 'firefox'])
>>> os.walk("foo", followlinks=False).next()
('foo', ['tetex', 'latex'], ['mozilla', 'firefox'])

我看到的唯一一个“问题”是,符号链接出现在目录列表中,而不是文件列表里。

在大多数情况下,这种行为是可以接受的,因为我们通常希望把文件列表中的所有条目都当作文件,而不需要去检查它们是否是符号链接。

这个来自python-dev的讨论简要地提到了这个问题。

“...把指向目录的符号链接放到文件列表中,而不是子目录列表中,并没有更好(这只是把问题转移到了其他用例,比如那些实际上想读取文件内容的情况)。”

还有来自链接问题页面的内容:

“例如,要计算一个目录下所有文件的行数,代码可以这样写:

for root, dirs, files in os.walk(top):
    for file in files:
        f = open(file)
        for n, l in enumerate(f, 1):
            pass
        print(file, n)

如果突然间,文件列表中出现了指向目录的符号链接,这样就会出问题。所以我不认为值得去改变这个。指向目录的符号链接与文件并没有多大关系,实际上这取决于具体的使用场景。”

撰写回答