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

Python中NewType兼容float但区分衍生类型及运算支持实现咨询

解决方案

要实现你的需求——让float可以直接传入接受Time的函数、Frequency传入时报错,同时支持Time与float运算返回Time类型,可以通过自定义类+函数重载的方式实现,具体如下:

1. 自定义类型类

继承float并重载运算符,确保运算结果仍保持对应类型:

class Time(float):
    # 重载乘法(Time * float)
    def __mul__(self, other: float) -> "Time":
        return Time(super().__mul__(other))
    
    # 重载反向乘法(float * Time)
    def __rmul__(self, other: float) -> "Time":
        return Time(super().__rmul__(other))
    
    # 可按需重载其他运算符(如+、-等)
    def __add__(self, other: "Time") -> "Time":
        return Time(super().__add__(other))

class Frequency(float):
    # 无需重载额外运算符,仅作为名义类型区分
    pass

2. 函数重载实现隐式兼容

通过@overload定义函数的类型签名,让类型检查器接受float和Time作为参数,同时拒绝Frequency:

from typing import overload, Union

@overload
def f(t: Time) -> None: ...

@overload
def f(t: float) -> None: ...

def f(t: Union[Time, float]) -> None:
    # 运行时自动将float转为Time实例
    t_time = Time(t) if isinstance(t, float) else t
    # 这里写业务逻辑
    print(f"处理时间: {t_time}")

3. 测试验证

# ✅ 直接传float,类型检查通过,运行时自动转为Time
f(0.1)

# ✅ 传Time实例,正常运行
f(Time(2.5))

# ❌ 传Frequency实例,mypy会抛出类型不兼容错误
f(Frequency(0.5))

# ✅ Time与float运算,结果类型为Time
t = Time(3.0)
result = t * 2.0
print(type(result))  # 输出 <class '__main__.Time'>

原理说明

  • 自定义Time和Frequency类继承自float,既保留了浮点数的所有特性,又作为名义类型实现了类型区分。
  • 函数重载让类型检查器允许float传入,同时拒绝Frequency(因为Frequency不在重载的参数类型列表中)。
  • 重载运算符确保Time与float运算后仍返回Time类型,满足类型检查和运行时的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:37:39