使用 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程序中访问Java类的简单示例
Apr 20 Python
Python基于回溯法子集树模板实现图的遍历功能示例
Sep 05 Python
python3 实现验证码图片切割的方法
Dec 07 Python
Python Matplotlib库安装与基本作图示例
Jan 09 Python
只需7行Python代码玩转微信自动聊天
Jan 27 Python
Flask框架学习笔记之使用Flask实现表单开发详解
Aug 12 Python
详解pyinstaller selenium python3 chrome打包问题
Oct 18 Python
python命令 -u参数用法解析
Oct 24 Python
Python基础之函数基本用法与进阶详解
Jan 02 Python
keras 实现轻量级网络ShuffleNet教程
Jun 19 Python
详解pandas映射与数据转换
Jan 22 Python
解决Pytorch中关于model.eval的问题
May 22 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
经典的星际争霸,满是回忆的BGM
2020/04/09 星际争霸
资料注册后发信小技巧
2006/10/09 PHP
PHP函数utf8转gb2312编码
2006/12/21 PHP
PHP执行速率优化技巧小结
2008/03/15 PHP
PHP版网站缓存加快打开速度的方法分享
2012/06/03 PHP
PHP ? EasyUI DataGrid 资料存的方式介绍
2012/11/07 PHP
强烈声明: 不要使用(include/require)_once
2013/06/06 PHP
jQuery+php实现ajax文件即时上传的详解
2013/06/17 PHP
PHP PDOStatement对象bindpram()、bindvalue()和bindcolumn之间的区别
2014/11/20 PHP
Codeigniter通过SimpleXML将xml转换成对象的方法
2015/03/19 PHP
php实现无限级分类(递归方法)
2015/08/06 PHP
无需数据库在线投票调查php代码
2016/07/20 PHP
php引用和拷贝的区别知识点总结
2019/09/23 PHP
利用jQuery 实现GridView异步排序、分页的代码
2010/02/06 Javascript
多浏览器兼容性比较好的复制到剪贴板的js代码
2011/10/09 Javascript
简介JavaScript中Math.cos()余弦方法的使用
2015/06/15 Javascript
easyui 中的datagrid跨页勾选问题的实现方法
2017/01/18 Javascript
使用Node.js搭建静态资源服务详细教程
2017/08/02 Javascript
vue项目刷新当前页面的三种方法
2018/12/04 Javascript
vue-router命名视图的使用讲解
2019/01/19 Javascript
如何解决js函数防抖、节流出现的问题
2019/06/17 Javascript
vue使用showdown并实现代码区域高亮的示例代码
2019/10/17 Javascript
vue实现在进行增删改操作后刷新页面
2020/08/05 Javascript
[01:08:43]DOTA2-DPC中国联赛定级赛 Phoenix vs DLG BO3第一场 1月9日
2021/03/11 DOTA
win7安装python生成随机数代码分享
2013/12/27 Python
压缩包密码破解示例分享(类似典破解)
2014/01/17 Python
python使用点操作符访问字典(dict)数据的方法
2015/03/16 Python
Python实现模拟登录及表单提交的方法
2015/07/25 Python
Spring实战之使用util:命名空间简化配置操作示例
2019/12/09 Python
django框架两个使用模板实例
2019/12/11 Python
基于python及pytorch中乘法的使用详解
2019/12/27 Python
python 制作简单的音乐播放器
2020/11/25 Python
销售辞职报告范文
2014/01/12 职场文书
关于青春的演讲稿
2014/05/05 职场文书
党员一帮一活动总结
2014/07/08 职场文书
离婚协议书怎么写(范本参考)
2014/09/30 职场文书