You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python递归检测txt含password时返回空列表问题修复

问题产生原因
  • 递归逻辑设计错误:每次进入search_pass_file函数都会新建一个空的list_of_pass结果列表,之前递归层中匹配到的文件路径不会被累计保存。只要遇到第一个触发异常的文件,代码就直接返回下一层递归的结果,当前层已经查到的匹配路径会被直接丢弃。
  • 遍历逻辑存在bug:你用for i in range(len(list_of_files))固定初始长度做循环,但循环内部不断调用pop()修改原列表长度,会导致遍历提前终止、漏处理文件,甚至索引报错。
  • 编码设置不合理:强制用utf-8编码打开所有txt文件,Windows环境下大量txt文件使用GBK、GB2312等本地编码,极易触发UnicodeDecodeError,进一步放大递归丢结果的问题。
  • 前置扫描逻辑有隐患:search_txt中调用os.walk时没有做异常处理,碰到系统保护、无权限访问的目录会直接抛出异常终止扫描,根本拿不到完整的txt文件列表。
原递归写法修复

要修复递归版本需要调整4个核心点:

  • 将结果列表作为可选参数传入递归函数,避免每次递归重置结果
  • 触发异常时不要直接返回递归结果,仅跳过当前异常文件,再递归处理剩余文件
  • 移除循环内修改原列表的pop()逻辑,避免遍历长度错乱
  • 给os.walk增加错误忽略配置,碰到无权限目录自动跳过

修复后的代码如下:

import os

def search_txt():
    """遍历C盘收集所有.txt后缀文件的完整路径"""
    list_of_txt = []
    # 加onerror参数忽略无权限目录的错误
    for dir_path, sub_dir, files in os.walk("C:\\", onerror=lambda e: None):
        for file in files:
            if file.endswith(".txt"):
                list_of_txt.append(os.path.join(dir_path, file))
    return list_of_txt


def search_pass_file(list_of_files: list, list_of_pass=None):
    """遍历文本文件查找包含"password"关键词的文件路径"""
    # 初始化结果列表,仅在第一次调用时创建空列表
    if list_of_pass is None:
        list_of_pass = []
    if not list_of_files:
        return list_of_pass
    # 取第一个文件处理,剩余文件留到递归层
    current_file = list_of_files[0]
    remaining_files = list_of_files[1:]
    try:
        # 增加errors="ignore"避免编码问题中断
        with open(current_file, encoding="utf8", errors="ignore") as f:
            for line in f:
                if "password" in line:
                    list_of_pass.append(current_file)
                    break  # 命中后不用继续读当前文件
    except (UnicodeDecodeError, PermissionError):
        pass  # 异常直接跳过当前文件即可
    # 递归处理剩余文件,传入已累计的结果列表
    return search_pass_file(remaining_files, list_of_pass)


if __name__ == '__main__':
    myList = search_txt()
    print(search_pass_file(myList))
更优的非递归实现

这个场景完全不需要用递归,普通循环实现逻辑更直白,也不会出现递归深度超限的问题(C盘文件数量极多时递归层数过大会触发栈溢出),性能和可维护性都更好:

import os

def search_txt():
    """遍历C盘收集所有.txt后缀文件的完整路径"""
    list_of_txt = []
    for dir_path, sub_dir, files in os.walk("C:\\", onerror=lambda e: None):
        for file in files:
            if file.lower().endswith(".txt"):  # 兼容.TXT大写后缀的情况
                list_of_txt.append(os.path.join(dir_path, file))
    return list_of_txt


def search_pass_file(list_of_files: list):
    """遍历文本文件查找包含"password"关键词的文件路径"""
    list_of_pass = []
    for file_path in list_of_files:
        try:
            # 逐行读取,不用一次性读全文件占内存,加errors忽略解码异常
            with open(file_path, encoding="utf-8", errors="ignore") as f:
                for line in f:
                    if "password" in line.lower():  # 兼容大写的PASSWORD关键词
                        list_of_pass.append(file_path)
                        break
        except (PermissionError, OSError): # 捕获更多IO相关异常,比如文件被占用
            continue
    return list_of_pass


if __name__ == '__main__':
    myList = search_txt()
    print(search_pass_file(myList))

额外优化点:如果需要更精准的编码识别,可以不用硬编码utf-8,改用编码检测类库识别文件编码后再打开,不过日常扫描场景用errors="ignore"已经足够覆盖需求。

内容的提问来源于stack exchange,提问作者Professor Seemo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:06:26