Python 如何在一行中捕获多个异常
用 except (ExceptionA, ExceptionB) as e 捕获多种异常,兼容各 Python 3 版本。Python 3.14 起不绑定异常时可省略括号;处理不同仍应拆分 except。
一句话回答:把异常类型写成元组:except (TypeError, ValueError) as e:——括号里是"或"的关系,任一异常触发都会进入该块,as e 拿到具体异常对象。绑定异常对象使用 as e;元组括号是兼容 Python 3 各版本的写法。Python 3.14 起,在没有 as 绑定时也允许省略该括号。
语法
try:
result = int(user_input) / divisor
except (ValueError, ZeroDivisionError) as e:
print(f'输入有误: {e}')
ValueError(无法转 int)和 ZeroDivisionError(除数为 0)任一发生,都会进入同一个处理块。
判断具体是哪种异常
except (ValueError, ZeroDivisionError) as e:
if isinstance(e, ValueError):
print('不是有效数字')
else:
print('除数不能为零')
如果两种异常的处理逻辑差异很大,分开写更清晰:
except ValueError:
print('请输入数字')
except ZeroDivisionError:
print('除数不能为零')
原则:处理逻辑相同才合并,不同就分开。 无差别合并多种异常往往会掩盖问题。
相关技巧
# 捕获 Exception 派生异常,不包括 SystemExit/KeyboardInterrupt 等 BaseException 直接子类
except Exception as e:
logger.exception(e)
# 异常类之间存在继承关系时,捕获父类即可覆盖子类
except OSError as e: # 同时覆盖 FileNotFoundError、PermissionError 等子类
print(f'文件操作失败: {e}')
常见问题(FAQ)
Q:except A, B 和 except (A, B) 有什么区别?
A:有版本差异。Python 2 中 except A, B 绑定异常给 B;Python 3.0–3.13 中这种无括号写法非法;Python 3.14 起 except A, B: 可表示捕获两种异常,但同时写 as e 仍需括号。跨版本代码建议始终写 except (A, B) as e:。
Q:能捕获"除某几种之外"的所有异常吗?
A:没有直接的排除语法。变通:先写具体的 except (TypeA, TypeB): raise(重新抛出),再写兜底的 except Exception——顺序上具体在前、兜底在后。
Q:合并捕获时 e 的类型是什么?
A:是实际抛出的那个异常的实例,类型是元组中某一个(或其子类)。需要区分时用 isinstance 判断。
核查依据
本文依据官方文档核对,示例未在实际业务环境运行;上线前请按部署版本、权限与数据范围验证。