工作中, 需要有历遍目录进行一些操作. python自带的os.walk很强大, 但是没有maxdepth这种层数参数.
os.walk是原本是一个递归. 下面是它的代码:
273 try:
274 # Note that listdir and error are globals in this module due
275 # to earlier import-*.
276 names = listdir(top)
277 except error, err:
278 if onerror is not None:
279 onerror(err)
280 return
281
282 dirs, nondirs = [], []
283 for name in names:
284 if isdir(join(top, name)):
285 dirs.append(name)
286 else:
287 nondirs.append(name)
288
289 if topdown:
290 yield top, dirs, nondirs
291 for name in dirs:
292 path = join(top, name)
293 if followlinks or not islink(path):
294 for x in walk(path, topdown, onerror, followlinks):
295 yield x
296 if not topdown:
297 yield top, dirs, nondirs
BTW:: 这里需要注意*nux的ENAMETOOLONG 错误.
递归无法按"层"历遍目录. 它只能一条一条路径走尽.
朋友说使用循环也可以实现递归, 这种代码从来没有写过. 也一直在迷惑。
但是受 http://www.devshed.com/c/a/Python/Basic-Threading-in-Python/2/ 的启发.
突然明白循环是怎么做到递归的。 于是自己使用循环自己写了一个历遍的函数:
def loop_walk(top, n):
stack = Queue.Queue()
sub_stack = Queue.Queue()
dirs = []
files = []
error = None
stack.put([top])
while True:
if stack.empty():
# stack被取完了, 下一层队列
stack, sub_stack = sub_stack, stack
if n <= 1:
yield [], [], None
return
else:
n -= 1
continue
else:
try:
top_list = stack.get(False)
except Queue.Empty:
yield [], [], None
return
for top in top_list:
try:
for item in os.listdir(top):
item = os.path.join(top, item)
if os.path.isdir(item):
dirs.append(item)
else:
files.append(item)
except:
# 出错, 比如没有权限
#traceback.print_exc()
error = top
yield dirs, files, error
if dirs:
sub_stack.put(dirs)
dirs = []
files = []
error = None
代码长度double了.........
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.