python递归遍历目录_递归遍历目录树

遍历目录树,即将一个目录中的所有文件都查询一遍,包含子目录中的文件,是一种经常会使用到的编程小技巧。在遍历过程中,叠加自己希望进行的操作,比如统计某一种类型的文件数量,或者对图片文件进行自动化压缩等等,可以实现很多非常有价值的功能。

Python编码时,使用递归来遍历,代码短小精干!

本文给出一个递归遍历目录树的Python代码框架, 此框架所使用的callback函数,只是仅仅将文件名称(普通文件)打印出来, 各位同学可以直接使用这个代码框架,修改callback函数,就可以实现自己的特殊功能需求。

代码框架

直接上代码吧:

#!/usr/bin/env python3

import os

import sys

from stat import *

def walktree(top, callback):

"""walk file tree from position top,

for each file, callback is called."""

for f in os.listdir(top):

pathname = os.path.join(top, f)

try:

mode = os.stat(pathname, follow_symlinks=False).st_mode

except:

continue

if S_ISDIR(mode):

# directory, recurse into it

walktree(pathname, callback)

else:

# file, whatever type, make the call back function

callback(pathname)

return

def printfile(file):

print('get to', file)

if __name__ == '__main__':

if (os.path.isabs(sys.argv[1]) and

os.path.exists(sys.argv[1])):

walktree(sys.argv[1], printfile)

代码解释

以上代码,关键是walktree这个递归调用自己的函数。函数入参top是一个绝对路径,在调用walktree之前判断是否有效,这个路径是遍历目录树开始的地方;入参callback是回调函数,对于每一个找到的文件,调用此函数进行处理。

以上代码使用printfile函数作为测试用回调函数,功能仅仅只是打印出pathname而已。根据您的需要,可以发挥的地方,也是这里。你可以统计某种类型的文件数量,对特种类型的文件进行某种你需要的处理等等。

一个细节:os.stat()函数的调用,指定了不要follow symbolic link file,这样保证了链接文件也能够被回调函数访问到,并且路径不会出现循环往复(如果有符号链接文件,链接的是一个路径)。

以上代码,用到了os.path模块的几个函数,用到了stat模块的函数,还有os模块的两个函数。

测试

假设以上代码存放在walktree.py文件中,你可以用下面这行命令来测试:

$sudo python3 walktree.py /

然后,你会看到所有的文件飞快地打印在屏幕上,由于输入的top参数是/,这是根路径,屏幕上文件名的打印,会持续好一会儿。sudo是为了防止permission deny的情况发生。

问题和局限

调用os.stat()函数的时候,no follow符号链接带来了一个问题,如果你用这段代码编译某个路径下的所有文件,如果有的文件是符号链接,并且链接的位置在这个top路径外面,那么这个文件本身将不会被访问到。

我在测试上面这段代码的时候,发现os.stat()函数有失败的情况,os.listdir()函数统计到了这个文件,但是在具体访问的时候却发现文件不存在,系统报FileNotFoundError异常。这样的异常基本上发生在与OS运行密切相关的路径中,因此加上了try...except结构。如果您还想对这样的异常进行处理,请自行在continue之前增加处理代码。对于一般用户文件,不会出现这样的异常。

-- EOF --

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值