使用 Python 实现文件递归遍历的三种方式


Posted in Python onJuly 18, 2018

今天有个脚本需要遍历获取某指定文件夹下面的所有文件,我记得很早前也实现过文件遍历和目录遍历的功能,于是找来看一看,嘿,不看不知道,看了吓一跳,原来之前我竟然用了这么搓的实现。

先发出来看看:

def getallfiles(dir):
"""遍历获取指定文件夹下面所有文件"""
  if os.path.isdir(dir):
    filelist = os.listdir(dir)
    for ret in filelist:
      filename = dir + "\\" + ret
      if os.path.isfile(filename):
        print filename

def getalldirfiles(dir, basedir):
"""遍历获取所有子文件夹下面所有文件"""
  if os.path.isdir(dir):
    getallfiles(dir)
    dirlist = os.listdir(dir)
    for dirret in dirlist:
      fullname = dir + "\\" + dirret
      if os.path.isdir(fullname):
        getalldirfiles(fullname, basedir)

我是用了 2 个函数,并且每个函数都用了一次 listdir,只是一次用来过滤文件,一次用来过滤文件夹,如果只是从功能实现上看,一点问题没有,但是这…太不优雅了吧。

开始着手优化,方案一:

def getallfiles(dir):
"""使用listdir循环遍历"""
  if not os.path.isdir(dir):
    print dir
    return
  dirlist = os.listdir(dir)
  for dirret in dirlist:
    fullname = dir + "\\" + dirret
    if os.path.isdir(fullname):
      getallfiles(fullname)
    else:
      print fullname

从上图可以看到,我把两个函数合并成了一个,只调用了一次 listdir,把文件和文件夹用 if~else~ 进行了分支处理,当然,自我调用的循环还是存在。

有木有更好的方式呢?网上一搜一大把,原来有一个现成的 os.walk() 函数可以用来处理文件(夹)的遍历,这样优化下就更简单了。

方案二:

def getallfilesofwalk(dir):
"""使用listdir循环遍历"""
  if not os.path.isdir(dir):
    print dir
    return
  dirlist = os.walk(dir)
  for root, dirs, files in dirlist:
    for file in files:
      print os.path.join(root, file)

只是从代码实现上看,方案二是最优雅简洁的了,但是再翻看 os.walk() 实现的源码就会发现,其实它内部还是调用的 listdir 完成具体的功能实现,只是它对输出结果做了下额外的处理而已。

附上os.walk()的源码:

from os.path import join, isdir, islink
# We may not have read permission for top, in which case we can't
# get a list of the files the directory contains. os.path.walk
# always suppressed the exception then, rather than blow up for a
# minor reason when (say) a thousand readable directories are still
# left to visit. That logic is copied here.
try:
  # Note that listdir and error are globals in this module due
  # to earlier import-*.
  names = listdir(top)
except error, err:
  if onerror is not None:
    onerror(err)
  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 followlinks or not islink(path):
    for x in walk(path, topdown, onerror, followlinks):
      yield x
if not topdown:
  yield top, dirs, nondirs

至于 listdir 和 walk 在输出时的不同点,主要就是 listdir 默认是按照文件和文件夹存放的字母顺序进行输出,而 walk 则是先输出顶级文件夹,然后是顶级文件,再输出第二级文件夹,以及第二级文件,以此类推,具体大家可以把上面脚本拷贝后自行验证。

总结

以上所述是小编给大家介绍的使用 Python 实现文件递归遍历的三种方式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python调用C/C++动态链接库的方法详解
Jul 22 Python
Python实现的简单发送邮件脚本分享
Nov 07 Python
python中查看变量内存地址的方法
May 05 Python
Python2.7下安装Scrapy框架步骤教程
Dec 22 Python
Python实现全排列的打印
Aug 18 Python
Python with用法:自动关闭文件进程
Jul 10 Python
python opencv鼠标事件实现画框圈定目标获取坐标信息
Apr 18 Python
python3 Scrapy爬虫框架ip代理配置的方法
Jan 17 Python
Python GUI库PyQt5图形和特效样式QSS介绍
Feb 25 Python
Tensorflow中的dropout的使用方法
Mar 13 Python
Python 文本滚动播放器的实现代码
Apr 25 Python
Python+OpenCV实现在图像上绘制矩形
Mar 21 Python
详解flask入门模板引擎
Jul 18 #Python
Sanic框架基于类的视图用法示例
Jul 18 #Python
flask入门之表单的实现
Jul 18 #Python
Flask入门之上传文件到服务器的方法示例
Jul 18 #Python
flask入门之文件上传与邮件发送示例
Jul 18 #Python
Sanic框架流式传输操作示例
Jul 18 #Python
django 发送邮件和缓存的实现代码
Jul 18 #Python
You might like
第二章 PHP入门基础之php代码写法
2011/12/30 PHP
php使用base64加密解密图片示例分享
2014/01/20 PHP
一个php生成16位随机数的代码(两种方法)
2014/09/16 PHP
PHP防止刷新重复提交页面的示例代码
2015/11/11 PHP
PHP表单验证内容是否为空的实现代码
2016/11/14 PHP
php获取数据库中数据的实现方法
2017/06/01 PHP
PHP定义字符串的四种方式详解
2018/02/06 PHP
thinkphp5.1 文件引入路径问题及注意事项
2018/06/13 PHP
编辑浪子版表单验证类
2007/05/12 Javascript
为EasyUI的Tab标签添加右键菜单的方法
2012/07/14 Javascript
浅谈Javascript如何实现匀速运动
2014/12/19 Javascript
详细解密jsonp跨域请求
2015/04/15 Javascript
利用JavaScript的AngularJS库制作电子名片的方法
2015/06/18 Javascript
解决vue单页使用keep-alive页面返回不刷新的问题
2018/03/13 Javascript
webpack 模块热替换原理
2018/04/09 Javascript
VUE在for循环里面根据内容值动态的加入class值的方法
2018/08/12 Javascript
JavaScript模板引擎应用场景及实现原理详解
2018/12/14 Javascript
JavaScript函数的特性与应用实践深入详解
2018/12/30 Javascript
微信小程序用户盒子、宫格列表的实现
2020/07/01 Javascript
[03:28]2014DOTA2国际邀请赛 走近EG战队天才中单Arteezy
2014/07/12 DOTA
[03:05]《我与DAC》之xiao8:DAC与BG
2018/03/27 DOTA
Django错误:TypeError at / 'bool' object is not callable解决
2019/08/16 Python
pytorch 使用单个GPU与多个GPU进行训练与测试的方法
2019/08/19 Python
解决pycharm最左侧Tool Buttons显示不全的问题
2019/12/17 Python
如何在Python 游戏中模拟引力
2020/03/27 Python
Jupyter notebook如何修改平台字体
2020/05/13 Python
网络工程师面试(三木通信技术有限公司)
2013/06/05 面试题
幼儿园毕业典礼主持词
2014/03/21 职场文书
初中班主任寄语
2014/04/04 职场文书
防灾减灾活动总结
2014/08/30 职场文书
学雷锋的心得体会
2014/09/04 职场文书
师范生免费教育协议书范本
2014/10/09 职场文书
党风廉政教育心得体会2016
2016/01/22 职场文书
八年级作文之一起的走过日子
2019/09/17 职场文书
详解解Django 多对多表关系的三种创建方式
2021/08/23 Python
使用Python开发贪吃蛇游戏 SnakeGame
2022/04/30 Python