Python面试题系列之05: 设计实现遍历目录及子目录,并抓取.txt文件?
Question
设计实现遍历目录及子目录,并抓取.txt文件?
知识点详解
这道题并不难,这里我们用三种思路来实现这个小需求。依次会用到os
模块、glob
模块、pathlib
模块。
方法一:利用os模块
python的os
库有很多和文件,路径,执行系统命令相关的功能。比如我们可以使用os.listdir()
方法来列出目录下的所有文件和目录放入一个列表进行返回,但是listdir()
函数不可对目录的子目录进行扫描。
很多时候我们需要将某个文件夹下的所有文件都要找出来,那么此时我们就需要os.walk()
。它通过在目录树中向下或向上游走,输出目录的文件名。
os.walk()
方法的语法格式如下:
os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
- top – 是你所要遍历的目录的地址
- topdown –可选,为 True,则优先遍历 top 目录,否则优先遍历 top 的子目录。
- onerror – 可选,需要一个 callable 对象,当 walk 需要异常时,会调用。
- followlinks – 可选,若为 True,则会遍历目录下的快捷方式。
该函数没有返回值,会使用yield关键字抛出一个存放当前该层目录(dirpath, dirnames, filenames)的三元组,最终将所有目录层的的结果变为一个生成器。
- dirpath是一个
string
,代表目录的路径; - dirnames是一个
list
,包含了dirpath下所有子目录的名字; - filenames是一个
list
,包含了非目录文件的名字。这些名字不包含路径信息,如果需要得到全路径,需要使用 os.path.join(dirpath, filename);
了解了os.walk
的语法后,接下来直接上代码,来实现这个需求。
import os
def get_files(dir, suffix):
res = []
for dirpath,dirnames,filenames in os.walk(dir):
for filename in filenames:
name, suf = os.path.splitext(filename)
if suf == suffix:
res.append(os.path.join(dirpath, filename))
print(res)
get_files("E:\Pythonista", '.txt')
方法二:利用glob模块
glob
模块可以使用Unix shell风格的通配符匹配符合特定格式的文件和文件夹,跟windows的文件搜索功能差不多。glob
模块并非调用一个子shell实现搜索功能,而是在内部调用了os.listdir()
和fnmatch.fnmatch()
。
glob模块支持的通配符如下:
*
匹配0或多个字符**
匹配所有文件、目录、子目录和子目录里的文件(Python 3.5版本新增)?
匹配1个字符,与正则表达式里的?不同[exp]
匹配指定范围内的字符,如:[1-9]匹配1至9范围内的字符[!exp]
匹配不在指定范围内的字符
接下来就利用glob
模块来实现这个需求,以下是具体代码:
from glob import iglob
def func(filepath, suffix):
for i in iglob(f"{filepath}/**/*{suffix}", recursive=True):
print(i)
if __name__ == "__main__":
suffix = ".txt"
func("E:\Pythonista", suffix)
自从Python 3.5
版本新增了**
通配符,glob
模块变得更加易用,真是太赞了😉
方法三:利用pathlib模块
pathlib
模块是Python 3.4
版本中新增的模块,pathlib
绝不仅仅是替换了os.path
那么简单,它可以说是路径处理的瑞士军刀。它完全采用面向对象的编程方式,尤其是在处理配置路径方面简直太方便了。
闲话少说,我们直接用Path().rglob
来递归遍历指定的文件。
from pathlib import Path
src = "E:\Pythonista"
for item in Path(src).rglob('*.txt'):
print(item)
简单几行代码,轻松搞定😎
Answer
无论用os
模块、还是glob
模块、或是pathlib
模块均可实现这一需求,详细代码见上文内容。
后记
上述三种方法都能实现这一需求,但哪种方法更加简便已不言而喻。所以还是希望大家能多了解一些Python
新版本的特性,紧跟技术前沿😁😁😁
可通过如下这个链接来了解Python 3
中每个版本加入的新特性。
https://docs.python.org/3.x/whatsnew/3.x.html
注:需要把x替换成实际版本号即可。好了,以上就是本篇全部内容。
备注:本篇首发于知识星球「人人都是Pythonista」。