os.walk()是否漏掉了指向目录的符号链接?
我有一个文件夹,里面有一些文件、一些子文件夹,还有一些指向文件的符号链接和指向文件夹的符号链接。
当我在这个文件夹里用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 个回答
你提到你在调用 os.walk()
时把 followlinks
设置为 False
。那么,这就是 正常的表现:
默认情况下,
walk()
不会进入指向目录的符号链接。如果你想访问这些符号链接指向的目录,可以把followlinks
设置为True
,前提是你的系统支持这种功能。
在我的电脑上,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)
如果突然间,文件列表中出现了指向目录的符号链接,这样就会出问题。所以我不认为值得去改变这个。指向目录的符号链接与文件并没有多大关系,实际上这取决于具体的使用场景。”