You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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 返回 False
  • value < Node(2) 返回 True

内容的提问来源于stack exchange,提问作者Dario

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:05:23