如何修改Python泛型Node类的比较TypeError异常信息为带具体泛型参数?
优化泛型类比较时的异常信息
问题描述
我实现了一个支持比较操作的泛型Node类,类型检查正常,但跨不兼容类型比较时,抛出的异常信息不够清晰。例如执行Node(1) < "0"时,默认异常仅显示:
TypeError: '<' not supported between instances of 'Node' and 'str'
而期望显示包含具体泛型参数的信息:
TypeError: '<' not supported between instances of 'Node[int]' and 'str'
原代码
import abc import typing class Comparable(typing.Protocol): """标识类型具有小于比较方法的协议""" @abc.abstractmethod def __lt__(self, other: typing.Any, /) -> bool: raise NotImplementedError T = typing.TypeVar("T", bound=Comparable) class Node(typing.Generic[T]): """包裹任意可比较值的泛型类""" def __init__(self, value: T) -> None: self.value = value def __lt__(self, __other: typing.Union[T, Node[T]]) -> bool: """实现小于比较操作""" try: if isinstance(__other, Node): return self.value < __other.value return self.value < __other except TypeError: return NotImplemented
解决方案
核心思路是:
- 在类中存储值的实际类型,用于构造带泛型参数的类名称
- 在比较时主动检测类型兼容性,或捕获异常后替换为包含泛型参数的清晰信息
修改后的代码:
import abc import typing class Comparable(typing.Protocol): """标识类型具有小于比较方法的协议""" @abc.abstractmethod def __lt__(self, other: typing.Any, /) -> bool: raise NotImplementedError T = typing.TypeVar("T", bound=Comparable) class Node(typing.Generic[T]): """包裹任意可比较值的泛型类""" def __init__(self, value: T) -> None: self.value = value # 存储值的实际类型,用于构造泛型类型名称 self._value_type = type(value) @property def _type_name(self) -> str: """返回包含泛型参数的类名称,如Node[int]""" return f"{self.__class__.__name__}[{self._value_type.__name__}]" def __lt__(self, __other: typing.Union[T, Node[T]]) -> bool: """实现小于比较操作,优化异常信息""" try: if isinstance(__other, Node): # 检查泛型参数是否兼容 if self._value_type != __other._value_type: raise TypeError( f"'<' not supported between instances of '{self._type_name}' and '{__other._type_name}'" ) return self.value < __other.value # 检查是否为兼容的原始类型 if not isinstance(__other, self._value_type): raise TypeError( f"'<' not supported between instances of '{self._type_name}' and '{type(__other).__name__}'" ) return self.value < __other except TypeError as e: # 保留自定义的清晰异常,其他TypeError重新包装 if "'<' not supported" in str(e): raise e other_type = __other._type_name if isinstance(__other, Node) else type(__other).__name__ raise TypeError( f"'<' not supported between instances of '{self._type_name}' and '{other_type}'" ) from e
验证效果
执行测试代码:
value = Node(1) print(value < "0")
将抛出预期的异常:
TypeError: '<' not supported between instances of 'Node[int]' and 'str'
同时,原有正常比较逻辑不受影响:
value < 1返回Falsevalue < Node(2)返回True
内容的提问来源于stack exchange,提问作者Dario
相关产品推荐
相关产品推荐

