Python借助__init_subclass__注册HTTPException子类抛异常触发BaseException派生TypeError求助
报错原因定位
- 核心问题出在子类注册的赋值逻辑上:你在
__init_subclass__钩子中给subclasses字典赋值时,存储的是类名字符串,而非类对象本身。 - 当你执行
raise HTTPExceptions.subclasses['Error501']时,实际传入raise语句的是字符串'Error501',不符合Python对可抛出异常必须是BaseException派生类型的要求,因此触发TypeError报错。
修复步骤
- 第一处逻辑修正:调整
__init_subclass__中的注册逻辑,将存储值从类名字符串改为类对象本身:
错误实现:
修正后实现:cls.subclasses[f'{cls.__name__}'] = cls.__name__cls.subclasses[cls.__name__] = cls - 第二处使用修正:Python中抛出异常需要抛出异常的实例,而非异常类本身,Werkzeug的
HTTPException也遵循这一设计,正确的抛出写法需要对类做实例化:
错误抛出写法:
正确抛出写法:raise HTTPExceptions.subclasses['Error501']raise HTTPExceptions.subclasses['Error501']() - 可选优化:注册时排除基类本身,避免把无意义的
HTTPExceptions基类存入字典,让注册逻辑更严谨:def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) # 跳过基类自身的注册 if cls is not HTTPExceptions: cls.subclasses[cls.__name__] = cls
修正后完整可运行代码示例
from werkzeug.exceptions import HTTPException class HTTPExceptions(HTTPException): subclasses = dict() def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) if cls is not HTTPExceptions: cls.subclasses[cls.__name__] = cls class Error501(HTTPExceptions): code = 501 # 正确触发异常 raise HTTPExceptions.subclasses['Error501']()
内容的提问来源于stack exchange,提问作者Mathew Daniels
相关产品推荐
相关产品推荐

