Python实现日志字符串查找功能始终返回False问题排查
问题根因
代码存在5个核心逻辑错误,直接导致运行结果不符合预期:
- 匹配对象完全错误:逐行循环中所有判断都写为
xxx_key not in logfile,其中logfile是打开的文件句柄对象,并非存储文件内容的字符串,字符串对文件句柄做成员判断永远返回False,因此所有if条件恒成立,每遍历一行就会把全部9条错误信息追加到列表中,最终错误列表永远非空。 - 判断逻辑位置错误:即使修正匹配对象,将key和当前遍历行
line做匹配,把「是否存在」的判断放在逐行循环内部也是错的——只要某一行不包含某个key就会追加错误,而正确逻辑是:只要整个文件任意一行包含该key,就算匹配成功。 - 变量作用域污染:存储错误的
lst是全局变量,没有在函数内初始化,每次运行函数都会往同一个全局列表追加内容,哪怕本次检测全量匹配,列表里残留的历史数据也会导致空判断失效。 - 返回值写法错误:
return True, print("Pre conditions are OK.")会让第二个返回值永远为None,因为print()函数本身没有返回值。 - 性能冗余:调用
readlines()会一次性把整个日志全部加载到内存,大日志场景下内存占用极高;且循环内重复判断所有key,哪怕key已经找到也会重复检查,运行效率低。
修复后代码
from collections import OrderedDict # 替换为实际业务中的全局变量值 # NR_log = "your_log_file_path.log" # recipe_name = "your_target_recipe_name" def pre_conditions(): # 函数内初始化错误列表,避免全局变量污染 missing_errors = [] # 集中维护待检查key和对应错误提示,后续扩展规则直接加键值对即可 check_items = { f'Executing script: {recipe_name}': '\nError: Script was not successfully executed.\n', 'Application was powered-up successfully, mode is: Review': '\nError: Application was failed to power up.\n', 'API recipe was chosen': "\nError: Recipe type [API] was not successfully chosen.\n", 'Lot was created successfully': "\nError: A lot was not successfully created.\n", 'Recipe execution started': "\nError: A timeout, recipe was not executed.\n", 'The Wafer was loaded successfully': "\nError: The wafer was not loaded.\n", 'Recipe run is paused': "\nError: The recipe was not paused.\n", 'Moving to Program mode': "\nError: The script was not switch to program key.\n", 'Recipe was saved successfully under the name: sanity_2022-06-22_Ver_5.1': "\nError: The recipe was not saved.\n" } # 初始待查找key集合 pending_keys = set(check_items.keys()) with open(NR_log, 'r', encoding='utf-8') as logfile: for line in logfile: # 直接迭代文件对象逐行读取,内存占用恒定 if not pending_keys: break # 所有key都已找到,提前终止循环,无需读剩余内容 # 检查当前行命中的待查key hit_keys = set() for key in pending_keys: if key in line: hit_keys.add(key) # 把命中的key从待查集合中移除 pending_keys -= hit_keys # 收集所有未命中key对应的错误信息 for key in pending_keys: missing_errors.append(check_items[key]) if not missing_errors: print("Pre conditions are OK.") return True # 去重后打印错误信息 for err in OrderedDict.fromkeys(missing_errors): print(err) return False if __name__ == "__main__": pre_conditions()
优化说明
- 移除了冗余的
readlines()调用,直接迭代文件对象逐行读取,大日志文件运行时内存占用更低 - 增加提前终止逻辑,所有目标字符串匹配完成后立刻停止读文件,运行速度更快
- 待检查规则集中配置,后续新增、修改检查项不需要改动核心遍历逻辑,可维护性更高
- 所有变量作用域收敛在函数内部,不会出现全局变量污染导致的逻辑异常
内容的提问来源于stack exchange,提问作者I'm not a robot
相关产品推荐
相关产品推荐

