使用 Python 实现文件递归遍历的三种方式
今天有个脚本需要遍历获取某指定文件夹下面的所有文件,我记得很早前也实现过文件遍历和目录遍历的功能,于是找来看一看,嘿,不看不知道,看了吓一跳,原来之前我竟然用了这么搓的实现。
先发出来看看:
defgetallfiles(dir): """遍历获取指定文件夹下面所有文件""" ifos.path.isdir(dir): filelist=os.listdir(dir) forretinfilelist: filename=dir+"\\"+ret ifos.path.isfile(filename): printfilename defgetalldirfiles(dir,basedir): """遍历获取所有子文件夹下面所有文件""" ifos.path.isdir(dir): getallfiles(dir) dirlist=os.listdir(dir) fordirretindirlist: fullname=dir+"\\"+dirret ifos.path.isdir(fullname): getalldirfiles(fullname,basedir)
我是用了2个函数,并且每个函数都用了一次listdir,只是一次用来过滤文件,一次用来过滤文件夹,如果只是从功能实现上看,一点问题没有,但是这…太不优雅了吧。
开始着手优化,方案一:
defgetallfiles(dir): """使用listdir循环遍历""" ifnotos.path.isdir(dir): printdir return dirlist=os.listdir(dir) fordirretindirlist: fullname=dir+"\\"+dirret ifos.path.isdir(fullname): getallfiles(fullname) else: printfullname
从上图可以看到,我把两个函数合并成了一个,只调用了一次listdir,把文件和文件夹用if~else~进行了分支处理,当然,自我调用的循环还是存在。
有木有更好的方式呢?网上一搜一大把,原来有一个现成的os.walk()函数可以用来处理文件(夹)的遍历,这样优化下就更简单了。
方案二:
defgetallfilesofwalk(dir): """使用listdir循环遍历""" ifnotos.path.isdir(dir): printdir return dirlist=os.walk(dir) forroot,dirs,filesindirlist: forfileinfiles: printos.path.join(root,file)
只是从代码实现上看,方案二是最优雅简洁的了,但是再翻看os.walk()实现的源码就会发现,其实它内部还是调用的listdir完成具体的功能实现,只是它对输出结果做了下额外的处理而已。
附上os.walk()的源码:
fromos.pathimportjoin,isdir,islink #Wemaynothavereadpermissionfortop,inwhichcasewecan't #getalistofthefilesthedirectorycontains.os.path.walk #alwayssuppressedtheexceptionthen,ratherthanblowupfora #minorreasonwhen(say)athousandreadabledirectoriesarestill #lefttovisit.Thatlogiciscopiedhere. try: #Notethatlistdiranderrorareglobalsinthismoduledue #toearlierimport-*. names=listdir(top) excepterror,err: ifonerrorisnotNone: onerror(err) return dirs,nondirs=[],[] fornameinnames: ifisdir(join(top,name)): dirs.append(name) else: nondirs.append(name) iftopdown: yieldtop,dirs,nondirs fornameindirs: path=join(top,name) iffollowlinksornotislink(path): forxinwalk(path,topdown,onerror,followlinks): yieldx ifnottopdown: yieldtop,dirs,nondirs
至于listdir和walk在输出时的不同点,主要就是listdir默认是按照文件和文件夹存放的字母顺序进行输出,而walk则是先输出顶级文件夹,然后是顶级文件,再输出第二级文件夹,以及第二级文件,以此类推,具体大家可以把上面脚本拷贝后自行验证。
总结
以上所述是小编给大家介绍的使用Python实现文件递归遍历的三种方式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!