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

如何子类化numbers.Number并为LispNumber实例赋予初始值?

解决LispNumber继承numbers.Number的实现问题

首先明确:numbers.Number是Python的抽象基类(ABC),它仅定义数值类型的接口规范,本身不提供具体的数值实现逻辑。针对你的需求,提供两种实用方案:

方案1:包装数值并代理操作(适配Lisp系统需求)

如果需要LispNumber作为独立类型存在,同时兼容Python数值操作,不需要纠结super()调用(因为numbers.Number的__init__本就不需要参数)。可以通过包装内置数值、代理魔法方法的方式实现,既避免逻辑冗余,又能完整支持数值行为:

import numbers

class LispNumber(numbers.Number):
    """兼容Lisp系统的数值类型,基于Python内置数值实现"""
    def __init__(self, thing):
        if not isinstance(thing, numbers.Number):
            raise TypeError(f"'{thing}' is not a Number")
        self.value = thing

    # 代理核心数值操作
    def __add__(self, other):
        val = other.value if isinstance(other, LispNumber) else other
        return LispNumber(self.value + val)
    
    def __radd__(self, other):
        return self.__add__(other)

    def __sub__(self, other):
        val = other.value if isinstance(other, LispNumber) else other
        return LispNumber(self.value - val)
    
    def __rsub__(self, other):
        return LispNumber(other - self.value)

    def __mul__(self, other):
        val = other.value if isinstance(other, LispNumber) else other
        return LispNumber(self.value * val)
    
    def __rmul__(self, other):
        return self.__mul__(other)

    # 按需补充其他方法,比如除法、相等判断、打印
    def __eq__(self, other):
        val = other.value if isinstance(other, LispNumber) else other
        return self.value == val
    
    def __repr__(self):
        return f"LispNumber({repr(self.value)})"

这里的value字段并非无用,它是LispNumber持有实际数值的载体,所有数值操作都基于它完成。如果需要更贴合Lisp风格,可将字段名改为_val或其他命名。

方案2:利用ABC注册机制(无额外包装)

如果不需要独立的LispNumber实例,仅需要让Python内置数值类型被识别为Lisp系统的数值类型,可以直接注册内置类型为LispNumber的虚拟子类:

import numbers

class LispNumber(numbers.Number):
    pass

# 将Python内置数值类型注册为LispNumber的子类
numbers.Integral.register(LispNumber)
numbers.Real.register(LispNumber)

这样isinstance(5, LispNumber)、isinstance(3.14, LispNumber)都会返回True,无需额外创建包装对象。但这种方式仅适用于不需要添加Lisp特定逻辑的场景。

关于super()的说明

numbers.Number作为抽象基类,没有需要初始化的内部状态,因此你的自定义__init__不需要调用super().__init__()——直接处理自身的数值校验和字段赋值即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:25:24