【发布时间】:2009-05-29 08:52:46
【问题描述】:
我需要一个文件系统遍历器,我可以指示它忽略遍历 我想保持不变的目录,包括所有子目录 在那个分支下面。 os.walk 和 os.path.walk 就是不这样做。
【问题讨论】:
标签: python directory-walk
我需要一个文件系统遍历器,我可以指示它忽略遍历 我想保持不变的目录,包括所有子目录 在那个分支下面。 os.walk 和 os.path.walk 就是不这样做。
【问题讨论】:
标签: python directory-walk
实际上,os.walk 可能完全符合您的要求。假设我在ignore 中有一个要忽略的目录列表(可能是一组)。那么这应该工作:
def my_walk(top_dir, ignore):
for dirpath, dirnames, filenames in os.walk(top_dir):
dirnames[:] = [
dn for dn in dirnames
if os.path.join(dirpath, dn) not in ignore ]
yield dirpath, dirnames, filenames
【讨论】:
可以就地修改os.walk的返回值的第二个元素:
[...] 调用者可以就地修改 dirnames 列表(可能使用 del 或 slice 赋值),并且 walk() 只会递归到名称保留在 dirnames 中的子目录;这可用于修剪搜索 [...]
def fwalk(root, predicate):
for dirpath, dirnames, filenames in os.walk(root):
dirnames[:] = [d for d in dirnames if predicate(r, d)]
yield dirpath, dirnames, filenames
现在,您只需为子目录输入一个谓词:
>>> ignore_list = [...]
>>> list(fwalk("some/root", lambda r, d: d not in ignore_list))
【讨论】:
这是最好和最简单的解决方案。
def walk(ignores):
global ignore
path = os.getcwd()
for root, dirs, files in os.walk(path):
for ignore in ignores:
if(ignore in dirs):
dirs.remove(ignore)
print root
print dirs
print files
walk(['.git', '.svn'])
请记住,如果您从 dirs 中删除文件夹名称,os.walk 将不会对其进行探索。
希望对你有帮助
【讨论】:
所以我做了这个home-roles walker函数:
import os
from os.path import join, isdir, islink, isfile
def mywalk(top, topdown=True, onerror=None, ignore_list=('.ignore',)):
try:
# Note that listdir and error are globals in this module due
# to earlier import-*.
names = os.listdir(top)
except Exception, err:
if onerror is not None:
onerror(err)
return
if len([1 for x in names if x in ignore_list]):
return
dirs, nondirs = [], []
for name in names:
if isdir(join(top, name)):
dirs.append(name)
else:
nondirs.append(name)
if topdown:
yield top, dirs, nondirs
for name in dirs:
path = join(top, name)
if not islink(path):
for x in mywalk(path, topdown, onerror, ignore_list):
yield x
if not topdown:
yield top, dirs, nondirs
【讨论】: