Python异常处理练习触发非BaseException派生的TypeError报错
报错产生的核心原因
两处连锁报错的根源是Python3完全废弃了Python2时代将字符串直接作为异常抛出、捕获的旧语法,这类写法常见于未适配Python3语法的老旧教程示例中,参考时很容易直接照搬出错。
Python对可触发、可捕获的异常对象有强制类型要求:所有合法的异常类型,必须是BaseException类的直接或间接子类,普通字符串、整数这类原生类型完全不满足这个要求。
这个连锁报错的触发逻辑是:当raise行抛出第一个类型错误后,解释器会尝试匹配当前代码块下的except子句来处理这个错误,在解析except后跟随的内容时,又发现它不符合可捕获异常的类型要求,因此触发了第二个类型错误。
- 首个报错
TypeError: exceptions must derive from BaseException:触发位置在raise "someError"行,代码直接尝试抛出一个字符串字面量,字符串属于str类型,不是合法的异常类型,解释器直接抛出类型错误阻断执行。 - 第二个报错
TypeError: catching classes that do not inherit from BaseException is not allowed:触发位置在except "someError"行,except关键字后面要求跟合法的异常类型/异常实例,这里直接放置字符串字面量,同样不符合类型规范。
本质上两段代码的问题都是把字符串当成了异常本身,既没有构造合法的异常实例,也没有定义合法的异常类。
合规修正方案
根据不同的使用场景,有两种常用的修正写法:
- 不需要专门定义专属异常类的快速实现
借助Python内置的Exception通用异常类,携带自定义的错误信息,同时在捕获时匹配异常内容:try: if '1' != 1: raise Exception("someError") else: print("someError has not occurred") except Exception as e: if str(e) == "someError": print("someError has occurred") - 业务场景需要自定义专属异常的规范写法
独立定义继承自Exception的自定义异常类,实现异常类型的精准匹配:# 自定义业务异常类,必须继承自Exception class SomeError(Exception): pass try: if '1' != 1: raise SomeError() else: print("someError has not occurred") except SomeError: print("someError has occurred")
注意:日常业务代码中自定义异常时,不要直接继承BaseException。BaseException是Python保留给解释器级别的异常(比如强制中断程序的KeyboardInterrupt、退出程序的SystemExit)的父类,业务自定义异常统一继承Exception即可,避免捕获到本不该被业务逻辑拦截的系统级异常。
内容的提问来源于stack exchange,提问作者Vaibhav Raj
相关产品推荐
相关产品推荐

