Python验证场景捕获通用异常是否合理?如何适配Pylint?
常规观点认为,Python中除非极特殊情况,否则不应捕获通用异常,但目前缺少对“极特殊情况”的明确定义。
我关注的场景是:通过调用各类函数对目标对象进行验证,若这些函数抛出错误,则判定对象无效。
我的具体场景是验证.json文件是否为有效的JSON,示例代码如下:
def validate_json(file_path: str): try: with open(file_path) as f: json.load(f) except Exception: return False return True def list_json_files(root_dir: str): return [file for file in glob.glob(root_dir + "*.json") if validate_json(file)]
注:上述代码未经过测试,仅用于演示场景。在诸多类似场景中,逐一排查验证过程中可能出现的所有异常似乎并无必要,且捕获特定异常会降低代码的前瞻性,例如外部库新增异常类型时可能出现问题。
该场景在我看来并不罕见,却从未被提及。更关键的是,作为Pylint用户,我不得不处理那些烦人的宽泛异常捕获警告,而消除这些警告只能在代码中添加大量#pylint: disable...注释。
我的问题是:该场景是否属于捕获通用异常的合理情况?若否,有什么更好的方案解决此类问题,尤其是能让Pylint认可的方案?
回答
这个场景完全属于捕获通用异常的合理情况。
核心原因在于你的validate_json函数本质是一个**“看门型”验证函数**:它的唯一职责就是判断输入的文件是否能被正常解析为JSON,任何导致解析失败的情况(不管是文件打不开、格式错误、权限问题还是库新增的异常),都应该被归类为“文件无效”,返回False是完全符合逻辑的。
如果非要纠结捕获特定异常,反而会陷入两个困境:
- 遗漏异常:比如
open可能抛出PermissionError、FileNotFoundError,json.load可能抛出JSONDecodeError,但如果后续Python或json库新增了其他相关异常类型,你的验证逻辑就会漏掉这些情况,导致原本应该被判定为无效的文件反而通过了验证。 - 代码冗余:把所有可能的异常列出来会让代码变得臃肿,完全没必要为了“规范”牺牲实用性。
针对Pylint的警告,有几个比硬加#pylint: disable=broad-except更优雅的方案:
- 局部精准禁用警告:不要全局禁用,而是在特定的
except块附近标注,明确告诉阅读者这里是故意捕获通用异常,比如:def validate_json(file_path: str): try: with open(file_path) as f: json.load(f) except Exception: # pylint: disable=broad-except return False return True - 配置Pylint规则:在项目的
.pylintrc文件中,给特定函数或模块放宽broad-except规则,比如添加:
这样就不用在代码里加注释,也能针对性消除警告。[MASTER] disable=broad-except:validate_json,list_json_files
总结来说,在这种“只要出错就判定无效”的验证场景下,捕获Exception是合理且实用的选择,不用被所谓的“规范”束缚,重点是让代码的逻辑清晰且符合业务需求。
内容的提问来源于stack exchange,提问作者magicsheep

