Python3.8多进程多线程环境下自定义异常无法正常捕获问题咨询
问题原因
核心原因是多进程场景下自定义异常类的身份不一致,内置异常是Python标准库全局统一的,所以不会有这个问题,自定义异常如果满足以下任意一种情况,就会出现捕获失败:
- 自定义异常没有放在公共模块,不同进程导入时的路径不一致,导致Python判定两个
NoDataReceived是完全不同的类,except分支匹配失败 - 使用
spawn模式启动多进程时,自定义异常定义在if __name__ == '__main__'代码块内,子进程重新导入主模块时不会加载这段代码,导致子进程内的NoDataReceived和主进程/其他进程的定义不是同一个类对象 - 自定义异常是在进程/线程内部动态定义的,不同执行单元拿到的类身份不同
修复方案
永久修复方案
将所有自定义异常统一放到独立的公共模块(例如exceptions.py)中,所有进程、线程的业务代码都从该模块统一导入异常类,不要在业务逻辑、主模块受保护代码块中定义异常类,保证所有执行单元用到的是同一个类对象。
示例目录结构:
project/ ├── exceptions.py # 存放所有自定义异常 ├── main.py # 主进程入口 └── worker.py # 业务逻辑代码
exceptions.py内容:
class Error(Exception): """Basic exception""" class NoDataReceived(Error): """Raised when there is no data"""
所有用到异常的地方都使用from exceptions import NoDataReceived导入即可。
临时排查/兜底方案
如果暂时没法定位类身份不一致的问题,可以先加通用异常捕获分支验证问题:
try: # 原有业务代码 except Exception as e: # 临时打印验证异常类身份 if type(e).__name__ == "NoDataReceived": print("err") # 原有NoDataReceived分支的处理逻辑 except ValueError as err: print('err') except NoDataReceived as err: print('err')
内容的提问来源于stack exchange,提问作者Jan Janáček
相关产品推荐
相关产品推荐

