Python实现:判断API返回的StopReason是否包含指定停止原因
问题描述
我有一个需要过滤的特定错误代码字符串列表:
DMS_WARNING_STOP_REASONS = ["Stop Reason RECOVERABLE_ERROR", "Stop Reason FATAL_ERROR", "Stop Reason STOPPED_DUE_TO_LOW_MEMORY", "Stop Reason STOPPED_DUE_TO_LOW_DISK", "Stop Reason FAILED" ]
API响应的StopReason字段有时会将这些停止原因嵌套在更长的字符串中,例如:
dict_response = {'name': 'job_name', 'Status': 'Stopped', 'StopReason': "terminated [reptask/replicationtask.c:2868] [1020101]\n Stop Reason FATAL_ERROR Error Level FATAL"}
我尝试过使用find等方法,但不知道如何实现检查DMS_WARNING_STOP_REASONS中的任一值是否为StopReason字段的子串。当前代码中的检查语句if x.get("StopReason") in self.DMS_WARNING_STOP_REASONS无法满足需求,寻求正确实现方式。
相关代码片段:
def process_tasks(self, all_tasks: list) -> dict: result = {} for env in self.envs: tasks = [x for x in all_tasks if env in self.__get_task_id(x)] warnings = [ {"name": self.__get_task_id(x), "Status": x["Status"],"StopReason": x.get("StopReason", "Stop Reason FAILED")} for x in tasks if x.get("StopReason") in self.DMS_WARNING_STOP_REASONS ] working = [... ] result[env] = {... } return result
解决方案
原判断逻辑是检查StopReason的完整值是否在错误列表中,这与需求完全相反——我们需要验证错误列表中的任意项是否是StopReason的子串。
可以用Python内置的any()函数结合生成器表达式实现该逻辑:
any(reason in x.get("StopReason", "") for reason in self.DMS_WARNING_STOP_REASONS)
细节说明
x.get("StopReason", ""):处理StopReason字段不存在的情况,避免因None调用字符串操作抛出异常any()函数会在找到第一个匹配的子串后立即停止遍历,保证了执行效率
修改后的warnings列表推导式如下:
warnings = [ {"name": self.__get_task_id(x), "Status": x["Status"],"StopReason": x.get("StopReason", "Stop Reason FAILED")} for x in tasks if any(reason in x.get("StopReason", "") for reason in self.DMS_WARNING_STOP_REASONS) ]
如果错误列表非常长,也可以考虑预编译正则表达式来匹配所有可能的原因,但对于当前场景,any()的实现已经足够简洁高效。
内容的提问来源于stack exchange,提问作者marcin2x4
相关产品推荐
相关产品推荐

