如何用Python 3编写递归函数搜索含指定字符串的TXT文件
修复你的TXT文件字符串搜索函数
嘿,我看了你写的这个递归搜索TXT文件的函数,思路是对的,但有几个关键问题会导致它无法正常工作,我帮你修正一下,顺便解释每个修改点:
原代码里的问题
- 递归调用
searchDir(fullname)时没传s参数,这样子目录里的搜索根本不知道要找什么字符串 - 用
directory + '/' + file拼接路径在Windows系统会出问题,应该用跨平台的路径处理方式 - 直接
open()文件后没手动关闭,容易造成文件句柄泄漏,最好用with语句自动管理 - 判断TXT文件的方式
fullname[-4:] == '.txt'不够稳,比如.TXT大写后缀或者文件名不足4个字符的情况会被漏掉 - 递归找到的结果没合并到主列表里,子目录匹配的文件不会出现在最终返回的列表中
- 异常处理太宽泛,会掩盖一些本应该被注意到的错误
修正后的完整代码
import os def searchDir(directory, s): """ Recursively searches 'directory' for .txt files that contain string s. """ filelist = [] # 用os.scandir比os.listdir更高效,还能直接获取文件属性 for entry in os.scandir(directory): full_path = entry.path try: if entry.is_dir(follow_symlinks=False): # 递归搜索子目录,把结果合并到当前列表 filelist.extend(searchDir(full_path, s)) else: # 更可靠的判断TXT文件,兼容大小写 _, file_ext = os.path.splitext(full_path) if file_ext.lower() == '.txt': # with语句自动关闭文件,避免资源泄漏 with open(full_path, 'r', encoding='utf-8') as f: # 逐行检查,找到匹配就加入列表并停止当前文件的读取 for line in f: if s in line: filelist.append(full_path) break except OSError as e: # 打印错误信息方便排查问题,而不是直接忽略 print(f"无法访问文件/目录 {full_path}: {e}") return filelist
关键修改说明
os.scandir()是比os.listdir()更优的选择,它能直接返回文件的属性信息,不用额外调用os.path.isdir(),效率更高- 递归时必须传递
s参数,同时用extend()把子目录的搜索结果合并到主列表,这样所有匹配的文件都会被收集到 - 用
os.path.splitext()配合lower()来判断后缀,不管是.txt还是.TXT都能识别,也不会因为文件名太短而出错 with语句会在代码块结束后自动关闭文件,哪怕中途出错也不会遗漏,比手动调用close()更安全- 指定
encoding='utf-8'可以避免不同系统下读取文件时的编码问题,减少乱码或者读取失败的情况 - 异常处理时打印具体错误,方便你排查哪些文件/目录无法访问,而不是默默忽略问题
现在这个函数就能正确递归遍历所有子目录,找到所有包含指定字符串的TXT文件,返回完整的文件路径列表啦。
内容的提问来源于stack exchange,提问作者Robert Cage
相关产品推荐
相关产品推荐

